Importing rustc-1.38.0
diff --git a/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp b/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp
index 64053a8..c76347e 100644
--- a/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/APFloatTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -869,6 +868,33 @@
   EXPECT_EQ(2.05e+12,  APFloat(APFloat::IEEEdouble(), "002.05000e+12").convertToDouble());
   EXPECT_EQ(2.05e-12,  APFloat(APFloat::IEEEdouble(), "002.05000e-12").convertToDouble());
 
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "1e").convertToDouble());
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "+1e").convertToDouble());
+  EXPECT_EQ(-1.0,      APFloat(APFloat::IEEEdouble(), "-1e").convertToDouble());
+
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "1.e").convertToDouble());
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "+1.e").convertToDouble());
+  EXPECT_EQ(-1.0,      APFloat(APFloat::IEEEdouble(), "-1.e").convertToDouble());
+
+  EXPECT_EQ(0.1,      APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());
+  EXPECT_EQ(0.1,      APFloat(APFloat::IEEEdouble(), "+.1e").convertToDouble());
+  EXPECT_EQ(-0.1,      APFloat(APFloat::IEEEdouble(), "-.1e").convertToDouble());
+
+  EXPECT_EQ(1.1,      APFloat(APFloat::IEEEdouble(), "1.1e").convertToDouble());
+  EXPECT_EQ(1.1,      APFloat(APFloat::IEEEdouble(), "+1.1e").convertToDouble());
+  EXPECT_EQ(-1.1,      APFloat(APFloat::IEEEdouble(), "-1.1e").convertToDouble());
+
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "1e+").convertToDouble());
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "1e-").convertToDouble());
+
+  EXPECT_EQ(0.1,      APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());
+  EXPECT_EQ(0.1,      APFloat(APFloat::IEEEdouble(), ".1e+").convertToDouble());
+  EXPECT_EQ(0.1,      APFloat(APFloat::IEEEdouble(), ".1e-").convertToDouble());
+
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "1.0e").convertToDouble());
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "1.0e+").convertToDouble());
+  EXPECT_EQ(1.0,      APFloat(APFloat::IEEEdouble(), "1.0e-").convertToDouble());
+
   // These are "carefully selected" to overflow the fast log-base
   // calculations in APFloat.cpp
   EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity());
@@ -1166,36 +1192,6 @@
   EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits");
 }
 
-TEST(APFloatTest, StringDecimalExponentDeath) {
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),   "1e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "+1e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "-1e"), "Exponent has no digits");
-
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),   "1.e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "+1.e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "-1.e"), "Exponent has no digits");
-
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),   ".1e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "+.1e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "-.1e"), "Exponent has no digits");
-
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),   "1.1e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "+1.1e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "-1.1e"), "Exponent has no digits");
-
-
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e+"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e-"), "Exponent has no digits");
-
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  ".1e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e+"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e-"), "Exponent has no digits");
-
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "1.0e"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e+"), "Exponent has no digits");
-  EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e-"), "Exponent has no digits");
-}
-
 TEST(APFloatTest, StringHexadecimalDeath) {
   EXPECT_DEATH(APFloat(APFloat::IEEEdouble(),  "0x"), "Invalid string");
   EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");
diff --git a/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp b/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp
index 8b876f3..4ab79e4 100644
--- a/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/APIntTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/APInt.cpp - APInt unit tests ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -1263,6 +1262,22 @@
   EXPECT_EQ(5U, APInt::getBitsNeeded("-10", 10));
   EXPECT_EQ(6U, APInt::getBitsNeeded("-19", 10));
   EXPECT_EQ(6U, APInt::getBitsNeeded("-20", 10));
+
+  EXPECT_EQ(1U, APInt::getBitsNeeded("-1", 10));
+  EXPECT_EQ(2U, APInt::getBitsNeeded("-2", 10));
+  EXPECT_EQ(3U, APInt::getBitsNeeded("-4", 10));
+  EXPECT_EQ(4U, APInt::getBitsNeeded("-8", 10));
+  EXPECT_EQ(5U, APInt::getBitsNeeded("-16", 10));
+  EXPECT_EQ(6U, APInt::getBitsNeeded("-23", 10));
+  EXPECT_EQ(6U, APInt::getBitsNeeded("-32", 10));
+  EXPECT_EQ(7U, APInt::getBitsNeeded("-64", 10));
+  EXPECT_EQ(8U, APInt::getBitsNeeded("-127", 10));
+  EXPECT_EQ(8U, APInt::getBitsNeeded("-128", 10));
+  EXPECT_EQ(9U, APInt::getBitsNeeded("-255", 10));
+  EXPECT_EQ(9U, APInt::getBitsNeeded("-256", 10));
+  EXPECT_EQ(10U, APInt::getBitsNeeded("-512", 10));
+  EXPECT_EQ(11U, APInt::getBitsNeeded("-1024", 10));
+  EXPECT_EQ(12U, APInt::getBitsNeeded("-1025", 10));
 }
 
 TEST(APIntTest, StringBitsNeeded16) {
@@ -2382,6 +2397,42 @@
   }
 }
 
+TEST(APIntTest, umul_ov) {
+  const std::pair<uint64_t, uint64_t> Overflows[] = {
+      {0x8000000000000000, 2},
+      {0x5555555555555556, 3},
+      {4294967296, 4294967296},
+      {4294967295, 4294967298},
+  };
+  const std::pair<uint64_t, uint64_t> NonOverflows[] = {
+      {0x7fffffffffffffff, 2},
+      {0x5555555555555555, 3},
+      {4294967295, 4294967297},
+  };
+
+  bool Overflow;
+  for (auto &X : Overflows) {
+    APInt A(64, X.first);
+    APInt B(64, X.second);
+    (void)A.umul_ov(B, Overflow);
+    EXPECT_TRUE(Overflow);
+  }
+  for (auto &X : NonOverflows) {
+    APInt A(64, X.first);
+    APInt B(64, X.second);
+    (void)A.umul_ov(B, Overflow);
+    EXPECT_FALSE(Overflow);
+  }
+
+  for (unsigned Bits = 1; Bits <= 5; ++Bits)
+    for (unsigned A = 0; A != 1u << Bits; ++A)
+      for (unsigned B = 0; B != 1u << Bits; ++B) {
+        APInt C = APInt(Bits, A).umul_ov(APInt(Bits, B), Overflow);
+        APInt D = APInt(2 * Bits, A) * APInt(2 * Bits, B);
+        EXPECT_TRUE(D.getHiBits(Bits).isNullValue() != Overflow);
+      }
+}
+
 TEST(APIntTest, SolveQuadraticEquationWrap) {
   // Verify that "Solution" is the first non-negative integer that solves
   // Ax^2 + Bx + C = "0 or overflow", i.e. that it is a correct solution
@@ -2467,4 +2518,24 @@
     Iterate(i);
 }
 
+TEST(APIntTest, MultiplicativeInverseExaustive) {
+  for (unsigned BitWidth = 1; BitWidth <= 16; ++BitWidth) {
+    for (unsigned Value = 0; Value < (1u << BitWidth); ++Value) {
+      APInt V = APInt(BitWidth, Value);
+      APInt MulInv =
+          V.zext(BitWidth + 1)
+              .multiplicativeInverse(APInt::getSignedMinValue(BitWidth + 1))
+              .trunc(BitWidth);
+      APInt One = V * MulInv;
+      if (!V.isNullValue() && V.countTrailingZeros() == 0) {
+        // Multiplicative inverse exists for all odd numbers.
+        EXPECT_TRUE(One.isOneValue());
+      } else {
+        // Multiplicative inverse does not exist for even numbers (and 0).
+        EXPECT_TRUE(MulInv.isNullValue());
+      }
+    }
+  }
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp b/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp
index a9b3071..1ad3871 100644
--- a/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/APSIntTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/APSIntTest.cpp - APSInt unit tests ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -160,4 +159,90 @@
 
 #endif
 
+TEST(APSIntTest, SignedHighBit) {
+  APSInt False(APInt(1, 0), false);
+  APSInt True(APInt(1, 1), false);
+  APSInt CharMin(APInt(8, 0), false);
+  APSInt CharSmall(APInt(8, 0x13), false);
+  APSInt CharBoundaryUnder(APInt(8, 0x7f), false);
+  APSInt CharBoundaryOver(APInt(8, 0x80), false);
+  APSInt CharLarge(APInt(8, 0xd9), false);
+  APSInt CharMax(APInt(8, 0xff), false);
+
+  EXPECT_FALSE(False.isNegative());
+  EXPECT_TRUE(False.isNonNegative());
+  EXPECT_FALSE(False.isStrictlyPositive());
+
+  EXPECT_TRUE(True.isNegative());
+  EXPECT_FALSE(True.isNonNegative());
+  EXPECT_FALSE(True.isStrictlyPositive());
+
+  EXPECT_FALSE(CharMin.isNegative());
+  EXPECT_TRUE(CharMin.isNonNegative());
+  EXPECT_FALSE(CharMin.isStrictlyPositive());
+
+  EXPECT_FALSE(CharSmall.isNegative());
+  EXPECT_TRUE(CharSmall.isNonNegative());
+  EXPECT_TRUE(CharSmall.isStrictlyPositive());
+
+  EXPECT_FALSE(CharBoundaryUnder.isNegative());
+  EXPECT_TRUE(CharBoundaryUnder.isNonNegative());
+  EXPECT_TRUE(CharBoundaryUnder.isStrictlyPositive());
+
+  EXPECT_TRUE(CharBoundaryOver.isNegative());
+  EXPECT_FALSE(CharBoundaryOver.isNonNegative());
+  EXPECT_FALSE(CharBoundaryOver.isStrictlyPositive());
+
+  EXPECT_TRUE(CharLarge.isNegative());
+  EXPECT_FALSE(CharLarge.isNonNegative());
+  EXPECT_FALSE(CharLarge.isStrictlyPositive());
+
+  EXPECT_TRUE(CharMax.isNegative());
+  EXPECT_FALSE(CharMax.isNonNegative());
+  EXPECT_FALSE(CharMax.isStrictlyPositive());
+}
+
+TEST(APSIntTest, UnsignedHighBit) {
+  APSInt False(APInt(1, 0));
+  APSInt True(APInt(1, 1));
+  APSInt CharMin(APInt(8, 0));
+  APSInt CharSmall(APInt(8, 0x13));
+  APSInt CharBoundaryUnder(APInt(8, 0x7f));
+  APSInt CharBoundaryOver(APInt(8, 0x80));
+  APSInt CharLarge(APInt(8, 0xd9));
+  APSInt CharMax(APInt(8, 0xff));
+
+  EXPECT_FALSE(False.isNegative());
+  EXPECT_TRUE(False.isNonNegative());
+  EXPECT_FALSE(False.isStrictlyPositive());
+
+  EXPECT_FALSE(True.isNegative());
+  EXPECT_TRUE(True.isNonNegative());
+  EXPECT_TRUE(True.isStrictlyPositive());
+
+  EXPECT_FALSE(CharMin.isNegative());
+  EXPECT_TRUE(CharMin.isNonNegative());
+  EXPECT_FALSE(CharMin.isStrictlyPositive());
+
+  EXPECT_FALSE(CharSmall.isNegative());
+  EXPECT_TRUE(CharSmall.isNonNegative());
+  EXPECT_TRUE(CharSmall.isStrictlyPositive());
+
+  EXPECT_FALSE(CharBoundaryUnder.isNegative());
+  EXPECT_TRUE(CharBoundaryUnder.isNonNegative());
+  EXPECT_TRUE(CharBoundaryUnder.isStrictlyPositive());
+
+  EXPECT_FALSE(CharBoundaryOver.isNegative());
+  EXPECT_TRUE(CharBoundaryOver.isNonNegative());
+  EXPECT_TRUE(CharBoundaryOver.isStrictlyPositive());
+
+  EXPECT_FALSE(CharLarge.isNegative());
+  EXPECT_TRUE(CharLarge.isNonNegative());
+  EXPECT_TRUE(CharLarge.isStrictlyPositive());
+
+  EXPECT_FALSE(CharMax.isNegative());
+  EXPECT_TRUE(CharMax.isNonNegative());
+  EXPECT_TRUE(CharMax.isStrictlyPositive());
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp b/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp
index 658f6b6..2ca81bd 100644
--- a/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/AnyTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/AnyTest.cpp - Any tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp b/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp
index e01d212..04b92c0 100644
--- a/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ArrayRefTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/ArrayRefTest.cpp - ArrayRef unit tests -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -34,10 +33,6 @@
 
 // Check that we can't accidentally assign a temporary location to an ArrayRef.
 // (Unfortunately we can't make use of the same thing with constructors.)
-//
-// Disable this check under MSVC; even MSVC 2015 isn't inconsistent between
-// std::is_assignable and actually writing such an assignment.
-#if !defined(_MSC_VER)
 static_assert(
     !std::is_assignable<ArrayRef<int *>&, int *>::value,
     "Assigning from single prvalue element");
@@ -50,7 +45,6 @@
 static_assert(
     !std::is_assignable<ArrayRef<int *>&, std::initializer_list<int *>>::value,
     "Assigning from an initializer list");
-#endif
 
 namespace {
 
@@ -249,4 +243,14 @@
   EXPECT_TRUE(AR2.equals(AR2Ref));
 }
 
+TEST(ArrayRefTest, OwningArrayRef) {
+  static const int A1[] = {0, 1};
+  OwningArrayRef<int> A(makeArrayRef(A1));
+  OwningArrayRef<int> B(std::move(A));
+  EXPECT_EQ(A.data(), nullptr);
+}
+
+static_assert(is_trivially_copyable<ArrayRef<int>>::value,
+              "trivially copyable");
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp
index 84290b3..559dcc5 100644
--- a/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BitVectorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/BitVectorTest.cpp - BitVector tests --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp b/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp
index 77635c6..f07e203 100644
--- a/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/BitmaskEnumTest.cpp - BitmaskEnum unit tests -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp
index 42a07bb..5d034ad 100644
--- a/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BreadthFirstIteratorTest.cpp
@@ -1,9 +1,8 @@
 //=== llvm/unittest/ADT/BreadthFirstIteratorTest.cpp - BFS iterator tests -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp b/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp
index be34a71..ebd0ce2 100644
--- a/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/BumpPtrListTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/BumpPtrListTest.cpp - BumpPtrList unit tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt b/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt
index 098b6b6..676ce18 100644
--- a/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ADT/CMakeLists.txt
@@ -18,6 +18,7 @@
   DenseSetTest.cpp
   DepthFirstIteratorTest.cpp
   EquivalenceClassesTest.cpp
+  FallibleIteratorTest.cpp
   FoldingSet.cpp
   FunctionExtrasTest.cpp
   FunctionRefTest.cpp
@@ -64,6 +65,7 @@
   StringExtrasTest.cpp
   StringMapTest.cpp
   StringRefTest.cpp
+  StringSetTest.cpp
   StringSwitchTest.cpp
   TinyPtrVectorTest.cpp
   TripleTest.cpp
@@ -71,4 +73,6 @@
   VariadicFunctionTest.cpp
   )
 
+target_link_libraries(ADTTests PRIVATE LLVMTestingSupport)
+
 add_dependencies(ADTTests intrinsics_gen)
diff --git a/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp b/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp
index 030fadb..66a67d9 100644
--- a/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DAGDeltaAlgorithmTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/DAGDeltaAlgorithmTest.cpp ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp b/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp
index 01dc1f3..5e28412 100644
--- a/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DeltaAlgorithmTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/DeltaAlgorithmTest.cpp ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp
index ee9c5dd..7e85ce7 100644
--- a/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DenseMapTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/DenseMapMap.cpp - DenseMap unit tests --*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -120,17 +119,8 @@
   // Lookup tests
   EXPECT_FALSE(this->Map.count(this->getKey()));
   EXPECT_TRUE(this->Map.find(this->getKey()) == this->Map.end());
-#if !defined(_MSC_VER) || defined(__clang__)
   EXPECT_EQ(typename TypeParam::mapped_type(),
             this->Map.lookup(this->getKey()));
-#else
-  // MSVC, at least old versions, cannot parse the typename to disambiguate
-  // TypeParam::mapped_type as a type. However, because MSVC doesn't implement
-  // two-phase name lookup, it also doesn't require the typename. Deal with
-  // this mutual incompatibility through specialized code.
-  EXPECT_EQ(TypeParam::mapped_type(),
-            this->Map.lookup(this->getKey()));
-#endif
 }
 
 // Constant map tests
diff --git a/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp
index 7368e2e..e6fe9ca 100644
--- a/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DenseSetTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/DenseSetTest.cpp - DenseSet unit tests --*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp
index 4169cd4..0e3e0e6 100644
--- a/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/DepthFirstIteratorTest.cpp
@@ -1,9 +1,8 @@
 //=== llvm/unittest/ADT/DepthFirstIteratorTest.cpp - DFS iterator tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp b/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp
index 57d588a..30eab6e 100644
--- a/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/EquivalenceClassesTest.cpp
@@ -1,9 +1,8 @@
 //=== llvm/unittest/ADT/EquivalenceClassesTest.cpp - the structure tests --===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/FallibleIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/FallibleIteratorTest.cpp
new file mode 100644
index 0000000..d338974
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ADT/FallibleIteratorTest.cpp
@@ -0,0 +1,291 @@
+//===- unittests/ADT/FallibleIteratorTest.cpp - fallible_iterator.h tests -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/fallible_iterator.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest-spi.h"
+#include "gtest/gtest.h"
+
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+
+using ItemValid = enum { ValidItem, InvalidItem };
+using LinkValid = enum { ValidLink, InvalidLink };
+
+class Item {
+public:
+  Item(ItemValid V) : V(V) {}
+  bool isValid() const { return V == ValidItem; }
+
+private:
+  ItemValid V;
+};
+
+// A utility to mock "bad collections". It supports both invalid items,
+// where the dereference operator may return an Error, and bad links
+// where the inc/dec operations may return an Error.
+// Each element of the mock collection contains a pair of a (possibly broken)
+// item and link.
+using FallibleCollection = std::vector<std::pair<Item, LinkValid>>;
+
+class FallibleCollectionWalker {
+public:
+  FallibleCollectionWalker(FallibleCollection &C, unsigned Idx)
+      : C(C), Idx(Idx) {}
+
+  Item &operator*() { return C[Idx].first; }
+
+  const Item &operator*() const { return C[Idx].first; }
+
+  Error inc() {
+    assert(Idx != C.size() && "Walking off end of (mock) collection");
+    if (C[Idx].second == ValidLink) {
+      ++Idx;
+      return Error::success();
+    }
+    return make_error<StringError>("cant get next object in (mock) collection",
+                                   inconvertibleErrorCode());
+  }
+
+  Error dec() {
+    assert(Idx != 0 && "Walking off start of (mock) collection");
+    --Idx;
+    if (C[Idx].second == ValidLink)
+      return Error::success();
+    return make_error<StringError>("cant get prev object in (mock) collection",
+                                   inconvertibleErrorCode());
+  }
+
+  friend bool operator==(const FallibleCollectionWalker &LHS,
+                         const FallibleCollectionWalker &RHS) {
+    assert(&LHS.C == &RHS.C && "Comparing iterators across collectionss.");
+    return LHS.Idx == RHS.Idx;
+  }
+
+private:
+  FallibleCollection &C;
+  unsigned Idx;
+};
+
+class FallibleCollectionWalkerWithStructDeref
+    : public FallibleCollectionWalker {
+public:
+  using FallibleCollectionWalker::FallibleCollectionWalker;
+
+  Item *operator->() { return &this->operator*(); }
+
+  const Item *operator->() const { return &this->operator*(); }
+};
+
+class FallibleCollectionWalkerWithFallibleDeref
+    : public FallibleCollectionWalker {
+public:
+  using FallibleCollectionWalker::FallibleCollectionWalker;
+
+  Expected<Item &> operator*() {
+    auto &I = FallibleCollectionWalker::operator*();
+    if (!I.isValid())
+      return make_error<StringError>("bad item", inconvertibleErrorCode());
+    return I;
+  }
+
+  Expected<const Item &> operator*() const {
+    const auto &I = FallibleCollectionWalker::operator*();
+    if (!I.isValid())
+      return make_error<StringError>("bad item", inconvertibleErrorCode());
+    return I;
+  }
+};
+
+TEST(FallibleIteratorTest, BasicSuccess) {
+
+  // Check that a basic use-case involing successful iteration over a
+  // "FallibleCollection" works.
+
+  FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, ValidLink}});
+
+  FallibleCollectionWalker begin(C, 0);
+  FallibleCollectionWalker end(C, 2);
+
+  Error Err = Error::success();
+  for (auto &Elem :
+       make_fallible_range<FallibleCollectionWalker>(begin, end, Err))
+    EXPECT_TRUE(Elem.isValid());
+  cantFail(std::move(Err));
+}
+
+TEST(FallibleIteratorTest, BasicFailure) {
+
+  // Check that a iteration failure (due to the InvalidLink state on element one
+  // of the fallible collection) breaks out of the loop and raises an Error.
+
+  FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, InvalidLink}});
+
+  FallibleCollectionWalker begin(C, 0);
+  FallibleCollectionWalker end(C, 2);
+
+  Error Err = Error::success();
+  for (auto &Elem :
+       make_fallible_range<FallibleCollectionWalker>(begin, end, Err))
+    EXPECT_TRUE(Elem.isValid());
+
+  EXPECT_THAT_ERROR(std::move(Err), Failed()) << "Expected failure value";
+}
+
+TEST(FallibleIteratorTest, NoRedundantErrorCheckOnEarlyExit) {
+
+  // Check that an early return from the loop body does not require a redundant
+  // check of Err.
+
+  FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, ValidLink}});
+
+  FallibleCollectionWalker begin(C, 0);
+  FallibleCollectionWalker end(C, 2);
+
+  Error Err = Error::success();
+  for (auto &Elem :
+       make_fallible_range<FallibleCollectionWalker>(begin, end, Err)) {
+    (void)Elem;
+    return;
+  }
+  // Err not checked, but should be ok because we exit from the loop
+  // body.
+}
+
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(FallibleIteratorTest, RegularLoopExitRequiresErrorCheck) {
+
+  // Check that Err must be checked after a normal (i.e. not early) loop exit
+  // by failing to check and expecting program death (due to the unchecked
+  // error).
+
+  EXPECT_DEATH(
+      {
+        FallibleCollection C({{ValidItem, ValidLink}, {ValidItem, ValidLink}});
+
+        FallibleCollectionWalker begin(C, 0);
+        FallibleCollectionWalker end(C, 2);
+
+        Error Err = Error::success();
+        for (auto &Elem :
+             make_fallible_range<FallibleCollectionWalker>(begin, end, Err))
+          (void)Elem;
+      },
+      "Program aborted due to an unhandled Error:")
+      << "Normal (i.e. not early) loop exit should require an error check";
+}
+#endif
+
+TEST(FallibleIteratorTest, RawIncrementAndDecrementBehavior) {
+
+  // Check the exact behavior of increment / decrement.
+
+  FallibleCollection C({{ValidItem, ValidLink},
+                        {ValidItem, InvalidLink},
+                        {ValidItem, ValidLink},
+                        {ValidItem, InvalidLink}});
+
+  {
+    // One increment from begin succeeds.
+    Error Err = Error::success();
+    auto I = make_fallible_itr(FallibleCollectionWalker(C, 0), Err);
+    ++I;
+    EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+  }
+
+  {
+    // Two increments from begin fail.
+    Error Err = Error::success();
+    auto I = make_fallible_itr(FallibleCollectionWalker(C, 0), Err);
+    ++I;
+    EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+    ++I;
+    EXPECT_THAT_ERROR(std::move(Err), Failed()) << "Expected failure value";
+  }
+
+  {
+    // One decement from element three succeeds.
+    Error Err = Error::success();
+    auto I = make_fallible_itr(FallibleCollectionWalker(C, 3), Err);
+    --I;
+    EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+  }
+
+  {
+    // One decement from element three succeeds.
+    Error Err = Error::success();
+    auto I = make_fallible_itr(FallibleCollectionWalker(C, 3), Err);
+    --I;
+    EXPECT_THAT_ERROR(std::move(Err), Succeeded());
+    --I;
+    EXPECT_THAT_ERROR(std::move(Err), Failed());
+  }
+}
+
+TEST(FallibleIteratorTest, CheckStructDerefOperatorSupport) {
+  // Check that the fallible_iterator wrapper forwards through to the
+  // underlying iterator's structure dereference operator if present.
+
+  FallibleCollection C({{ValidItem, ValidLink},
+                        {ValidItem, ValidLink},
+                        {InvalidItem, InvalidLink}});
+
+  FallibleCollectionWalkerWithStructDeref begin(C, 0);
+
+  {
+    Error Err = Error::success();
+    auto I = make_fallible_itr(begin, Err);
+    EXPECT_TRUE(I->isValid());
+    cantFail(std::move(Err));
+  }
+
+  {
+    Error Err = Error::success();
+    const auto I = make_fallible_itr(begin, Err);
+    EXPECT_TRUE(I->isValid());
+    cantFail(std::move(Err));
+  }
+}
+
+TEST(FallibleIteratorTest, CheckDerefToExpectedSupport) {
+
+  // Check that the fallible_iterator wrapper forwards value types, in
+  // particular llvm::Expected, correctly.
+
+  FallibleCollection C({{ValidItem, ValidLink},
+                        {InvalidItem, ValidLink},
+                        {ValidItem, ValidLink}});
+
+  FallibleCollectionWalkerWithFallibleDeref begin(C, 0);
+  FallibleCollectionWalkerWithFallibleDeref end(C, 3);
+
+  Error Err = Error::success();
+  auto I = make_fallible_itr(begin, Err);
+  auto E = make_fallible_end(end);
+
+  Expected<Item> V1 = *I;
+  EXPECT_THAT_ERROR(V1.takeError(), Succeeded());
+  ++I;
+  EXPECT_NE(I, E); // Implicitly check error.
+  Expected<Item> V2 = *I;
+  EXPECT_THAT_ERROR(V2.takeError(), Failed());
+  ++I;
+  EXPECT_NE(I, E); // Implicitly check error.
+  Expected<Item> V3 = *I;
+  EXPECT_THAT_ERROR(V3.takeError(), Succeeded());
+  ++I;
+  EXPECT_EQ(I, E);
+  cantFail(std::move(Err));
+}
+
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp b/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp
index f5b1b71..c03353f 100644
--- a/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/FoldingSet.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/FoldingSetTest.cpp -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp b/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp
index d85962e..bbbb045 100644
--- a/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/FunctionExtrasTest.cpp
@@ -1,9 +1,8 @@
 //===- FunctionExtrasTest.cpp - Unit tests for function type erasure ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp b/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp
index b7ef7d7..a599bee 100644
--- a/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/FunctionRefTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/MakeUniqueTest.cpp - make_unique unit tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp b/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp
index d96dd7e..66d63d4 100644
--- a/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/HashingTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp
index 3b8ede8..2983618 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListBaseTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/IListBaseTest.cpp - ilist_base unit tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp
index 8b2aa62..559e32d 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListIteratorTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/IListIteratorTest.cpp - ilist_iterator unit tests ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp
index 8819ab1..65f85fc 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListNodeBaseTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/IListNodeBaseTest.cpp - ilist_node_base unit tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp
index 51bebc2..cf775eb 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListNodeTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/IListNodeTest.cpp - ilist_node unit tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp
index bd60c90..1f4a831 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListSentinelTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/IListSentinelTest.cpp - ilist_sentinel unit tests ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IListTest.cpp b/src/llvm-project/llvm/unittests/ADT/IListTest.cpp
index 0dee4c1..18f6c41 100644
--- a/src/llvm-project/llvm/unittests/ADT/IListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IListTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/IListTest.cpp - ilist unit tests ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -208,6 +207,12 @@
 } // end namespace
 
 namespace llvm {
+// These nodes are stack-allocated for testing purposes, so don't let the ilist
+// own or delete them.
+template <> struct ilist_alloc_traits<NodeWithCallback> {
+  static void deleteNode(NodeWithCallback *) {}
+};
+
 template <> struct ilist_callback_traits<NodeWithCallback> {
   void addNodeToList(NodeWithCallback *N) { N->IsInList = true; }
   void removeNodeFromList(NodeWithCallback *N) { N->IsInList = false; }
@@ -248,6 +253,30 @@
   ASSERT_TRUE(N.WasTransferred);
 }
 
+TEST(IListTest, sameListSplice) {
+  NodeWithCallback N1(1);
+  NodeWithCallback N2(2);
+  ASSERT_FALSE(N1.WasTransferred);
+  ASSERT_FALSE(N2.WasTransferred);
+
+  ilist<NodeWithCallback> L1;
+  L1.insert(L1.end(), &N1);
+  L1.insert(L1.end(), &N2);
+  ASSERT_EQ(2u, L1.size());
+  ASSERT_EQ(&N1, &L1.front());
+  ASSERT_FALSE(N1.WasTransferred);
+  ASSERT_FALSE(N2.WasTransferred);
+
+  // Swap the nodes with splice inside the same list. Check that we get the
+  // transfer callback.
+  L1.splice(L1.begin(), L1, std::next(L1.begin()), L1.end());
+  ASSERT_EQ(2u, L1.size());
+  ASSERT_EQ(&N1, &L1.back());
+  ASSERT_EQ(&N2, &L1.front());
+  ASSERT_FALSE(N1.WasTransferred);
+  ASSERT_TRUE(N2.WasTransferred);
+}
+
 struct PrivateNode : private ilist_node<PrivateNode> {
   friend struct llvm::ilist_detail::NodeAccess;
 
diff --git a/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp b/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp
index 280cb2e..b0b1e0e 100644
--- a/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ImmutableListTest.cpp
@@ -1,9 +1,8 @@
 //===--------- ImmutableListTest.cpp - ImmutableList unit tests --*- C++ -*-==//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. Lee LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -268,4 +267,7 @@
   ASSERT_EQ(6, i);
 }
 
+static_assert(is_trivially_copyable<ImmutableList<Wrapper<long>>>::value,
+              "trivially copyable");
+
 } // namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp
index 23ca168..fa61816 100644
--- a/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ImmutableMapTest.cpp
@@ -1,9 +1,8 @@
 //===----------- ImmutableMapTest.cpp - ImmutableMap unit tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp
index 35ac2c1..9fe7a80 100644
--- a/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ImmutableSetTest.cpp
@@ -1,9 +1,8 @@
 //===----------- ImmutableSetTest.cpp - ImmutableSet unit tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp b/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp
index fc908c1..1c15d2c 100644
--- a/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IntEqClassesTest.cpp
@@ -1,9 +1,8 @@
 //===---- ADT/IntEqClassesTest.cpp - IntEqClasses unit tests ----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp
index 513c063..170d152 100644
--- a/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IntervalMapTest.cpp
@@ -1,9 +1,8 @@
 //===---- ADT/IntervalMapTest.cpp - IntervalMap unit tests ------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp b/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
index 83dc137..c248b04 100644
--- a/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/ADT/IntrusiveRefCntPtrTest.cpp ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp
index 902ddfb..f46f109 100644
--- a/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/IteratorTest.cpp
@@ -1,9 +1,8 @@
 //===- IteratorTest.cpp - Unit tests for iterator utilities ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp b/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp
index 3b4938a..c0c1096 100644
--- a/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/MakeUniqueTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/MakeUniqueTest.cpp - make_unique unit tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp
index 16e9b5a..b8fdbdd 100644
--- a/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/MapVectorTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/ADT/MapVectorTest.cpp - MapVector unit tests ----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp
index d8c48a7..61e45e3 100644
--- a/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/MappedIteratorTest.cpp
@@ -1,9 +1,8 @@
 //===------ MappedIteratorTest.cpp - Unit tests for mapped_iterator -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp b/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp
index 20bc9da..1f26c10 100644
--- a/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/OptionalTest.cpp
@@ -1,17 +1,28 @@
 //===- llvm/unittest/ADT/OptionalTest.cpp - Optional unit tests -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest-spi.h"
 #include "gtest/gtest.h"
 
+#include <array>
+
+
 using namespace llvm;
 
+static_assert(is_trivially_copyable<Optional<int>>::value,
+          "trivially copyable");
+
+static_assert(is_trivially_copyable<Optional<std::array<int, 3>>>::value,
+              "trivially copyable");
+
 namespace {
 
 struct NonDefaultConstructible {
@@ -41,6 +52,10 @@
 unsigned NonDefaultConstructible::Destructions = 0;
 unsigned NonDefaultConstructible::CopyAssignments = 0;
 
+static_assert(
+      !is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
+      "not trivially copyable");
+
 // Test fixture
 class OptionalTest : public testing::Test {
 };
@@ -199,6 +214,10 @@
 };
 unsigned MultiArgConstructor::Destructions = 0;
 
+static_assert(
+  !is_trivially_copyable<Optional<MultiArgConstructor>>::value,
+  "not trivially copyable");
+
 TEST_F(OptionalTest, Emplace) {
   MultiArgConstructor::ResetCounts();
   Optional<MultiArgConstructor> A;
@@ -246,6 +265,9 @@
 unsigned MoveOnly::Destructions = 0;
 unsigned MoveOnly::MoveAssignments = 0;
 
+static_assert(!is_trivially_copyable<Optional<MoveOnly>>::value,
+              "not trivially copyable");
+
 TEST_F(OptionalTest, MoveOnlyNull) {
   MoveOnly::ResetCounts();
   Optional<MoveOnly> O;
@@ -347,6 +369,9 @@
 unsigned Immovable::Constructions = 0;
 unsigned Immovable::Destructions = 0;
 
+static_assert(!is_trivially_copyable<Optional<Immovable>>::value,
+              "not trivially copyable");
+
 TEST_F(OptionalTest, ImmovableEmplace) {
   Optional<Immovable> A;
   Immovable::ResetCounts();
@@ -518,5 +543,52 @@
   CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
 }
 
-} // end anonymous namespace
+struct ComparableAndStreamable {
+  friend bool operator==(ComparableAndStreamable,
+                         ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
+    return true;
+  }
 
+  friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) {
+    return OS << "ComparableAndStreamable";
+  }
+
+  static Optional<ComparableAndStreamable> get() {
+    return ComparableAndStreamable();
+  }
+};
+
+TEST_F(OptionalTest, StreamOperator) {
+  auto to_string = [](Optional<ComparableAndStreamable> O) {
+    SmallString<16> S;
+    raw_svector_ostream OS(S);
+    OS << O;
+    return S;
+  };
+  EXPECT_EQ("ComparableAndStreamable",
+            to_string(ComparableAndStreamable::get()));
+  EXPECT_EQ("None", to_string(None));
+}
+
+struct Comparable {
+  friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
+    return true;
+  }
+  static Optional<Comparable> get() { return Comparable(); }
+};
+
+TEST_F(OptionalTest, UseInUnitTests) {
+  // Test that we invoke the streaming operators when pretty-printing values in
+  // EXPECT macros.
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, ComparableAndStreamable::get()),
+                          "Expected: llvm::None\n"
+                          "      Which is: None\n"
+                          "To be equal to: ComparableAndStreamable::get()\n"
+                          "      Which is: ComparableAndStreamable");
+
+  // Test that it is still possible to compare objects which do not have a
+  // custom streaming operator.
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(llvm::None, Comparable::get()), "object");
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp
index 199a670..24df398 100644
--- a/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PackedVectorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/PackedVectorTest.cpp - PackedVector tests --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp
index 695ea12..d24c8b8 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerEmbeddedIntTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/PointerEmbeddedIntTest.cpp -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp
index 985fdba..6b3a4c0 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerIntPairTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/PointerIntPairTest.cpp - Unit tests --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -62,6 +61,9 @@
   Pair2.setPointerAndInt(&s, E::Case3);
   EXPECT_EQ(&s, Pair2.getPointer());
   EXPECT_EQ(E::Case3, Pair2.getInt());
+
+  static_assert(is_trivially_copyable<PointerIntPair<S *, 2, E>>::value,
+                "trivially copyable");
 }
 
 TEST(PointerIntPairTest, DefaultInitialize) {
@@ -97,6 +99,11 @@
 
   EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
             PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
+
+  static_assert(
+      is_trivially_copyable<
+          PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits>>::value,
+      "trivially copyable");
 }
 
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp
index a4faea6..fbf59f3 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerSumTypeTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/PointerSumTypeTest.cpp ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp b/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp
index 360c371..cd6e980 100644
--- a/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PointerUnionTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/PointerUnionTest.cpp - Optional unit tests -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -69,4 +68,41 @@
   EXPECT_EQ(n.get<int *>(), (int *)nullptr);
 }
 
+template<int I> struct alignas(8) Aligned {};
+
+typedef PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *,
+                     Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *>
+    PU8;
+
+TEST_F(PointerUnionTest, ManyElements) {
+  Aligned<0> a0;
+  Aligned<7> a7;
+
+  PU8 a = &a0;
+  EXPECT_TRUE(a.is<Aligned<0>*>());
+  EXPECT_FALSE(a.is<Aligned<1>*>());
+  EXPECT_FALSE(a.is<Aligned<2>*>());
+  EXPECT_FALSE(a.is<Aligned<3>*>());
+  EXPECT_FALSE(a.is<Aligned<4>*>());
+  EXPECT_FALSE(a.is<Aligned<5>*>());
+  EXPECT_FALSE(a.is<Aligned<6>*>());
+  EXPECT_FALSE(a.is<Aligned<7>*>());
+  EXPECT_EQ(a.dyn_cast<Aligned<0>*>(), &a0);
+  EXPECT_EQ(*a.getAddrOfPtr1(), &a0);
+
+  a = &a7;
+  EXPECT_FALSE(a.is<Aligned<0>*>());
+  EXPECT_FALSE(a.is<Aligned<1>*>());
+  EXPECT_FALSE(a.is<Aligned<2>*>());
+  EXPECT_FALSE(a.is<Aligned<3>*>());
+  EXPECT_FALSE(a.is<Aligned<4>*>());
+  EXPECT_FALSE(a.is<Aligned<5>*>());
+  EXPECT_FALSE(a.is<Aligned<6>*>());
+  EXPECT_TRUE(a.is<Aligned<7>*>());
+  EXPECT_EQ(a.dyn_cast<Aligned<7>*>(), &a7);
+
+  EXPECT_TRUE(a == PU8(&a7));
+  EXPECT_TRUE(a != PU8(&a0));
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp
index 20c938e..8e53247 100644
--- a/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PostOrderIteratorTest.cpp
@@ -1,9 +1,8 @@
 //===- PostOrderIteratorTest.cpp - PostOrderIterator unit tests -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/ADT/PostOrderIterator.h"
diff --git a/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp b/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp
index 040a11f..4dfdd5f 100644
--- a/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/PriorityWorklistTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/PriorityWorklist.cpp -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp b/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp
index edc1ced..eb18526 100644
--- a/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/RangeAdapterTest.cpp
@@ -1,9 +1,8 @@
 //===- RangeAdapterTest.cpp - Unit tests for range adapters  --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp
index 57a999b..4835095 100644
--- a/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SCCIteratorTest.cpp
@@ -1,9 +1,8 @@
 //===----- llvm/unittest/ADT/SCCIteratorTest.cpp - SCCIterator tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp b/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp
index e65e71f..8704ddd 100644
--- a/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1,9 +1,8 @@
 //===- STLExtrasTest.cpp - Unit tests for STL extras ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -447,4 +446,37 @@
   EXPECT_FALSE(is_splat(V));
 }
 
+TEST(STLExtrasTest, to_address) {
+  int *V1 = new int;
+  EXPECT_EQ(V1, to_address(V1));
+
+  // Check fancy pointer overload for unique_ptr
+  std::unique_ptr<int> V2 = make_unique<int>(0);
+  EXPECT_EQ(V2.get(), to_address(V2));
+
+  V2.reset(V1);
+  EXPECT_EQ(V1, to_address(V2));
+  V2.release();
+
+  // Check fancy pointer overload for shared_ptr
+  std::shared_ptr<int> V3 = std::make_shared<int>(0);
+  std::shared_ptr<int> V4 = V3;
+  EXPECT_EQ(V3.get(), V4.get());
+  EXPECT_EQ(V3.get(), to_address(V3));
+  EXPECT_EQ(V4.get(), to_address(V4));
+
+  V3.reset(V1);
+  EXPECT_EQ(V1, to_address(V3));
+}
+
+TEST(STLExtrasTest, partition_point) {
+  std::vector<int> V = {1, 3, 5, 7, 9};
+
+  // Range version.
+  EXPECT_EQ(V.begin() + 3,
+            partition_point(V, [](unsigned X) { return X < 7; }));
+  EXPECT_EQ(V.begin(), partition_point(V, [](unsigned X) { return X < 1; }));
+  EXPECT_EQ(V.end(), partition_point(V, [](unsigned X) { return X < 50; }));
+}
+
 } // namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp b/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp
index ab11dff..1437652 100644
--- a/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/ScopeExitTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/ScopeExit.cpp - Scope exit unit tests --*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp b/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp
index cc82f86..4356bb1 100644
--- a/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SequenceTest.cpp
@@ -1,9 +1,8 @@
 //===- SequenceTest.cpp - Unit tests for a sequence abstraciton -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp
index b8cac0d..b9fef78 100644
--- a/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SetVectorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/SetVector.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp b/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp
index a354f33..9b8ffac 100644
--- a/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SimpleIListTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ADT/SimpleIListTest.cpp - simple_ilist unit tests --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp
index 76f9cf7..cff1632 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallPtrSetTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/SmallPtrSetTest.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp
index 3391a5c..8fb78b0 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallSetTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/SmallSetTest.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp
index 995ef8e..6868381 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallStringTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/SmallStringTest.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp
index 9c501bb..dbe4048 100644
--- a/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SmallVectorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/SmallVectorTest.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -909,63 +908,69 @@
   EmplaceableArg<3> A3(true);
   {
     SmallVector<Emplaceable, 3> V;
-    V.emplace_back();
+    Emplaceable &back = V.emplace_back();
+    EXPECT_TRUE(&back == &V.back());
     EXPECT_TRUE(V.size() == 1);
-    EXPECT_TRUE(V.back().State == ES_Emplaced);
-    EXPECT_TRUE(V.back().A0.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+    EXPECT_TRUE(back.State == ES_Emplaced);
+    EXPECT_TRUE(back.A0.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A1.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A3.State == EAS_Defaulted);
   }
   {
     SmallVector<Emplaceable, 3> V;
-    V.emplace_back(std::move(A0));
+    Emplaceable &back = V.emplace_back(std::move(A0));
+    EXPECT_TRUE(&back == &V.back());
     EXPECT_TRUE(V.size() == 1);
-    EXPECT_TRUE(V.back().State == ES_Emplaced);
-    EXPECT_TRUE(V.back().A0.State == EAS_RValue);
-    EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+    EXPECT_TRUE(back.State == ES_Emplaced);
+    EXPECT_TRUE(back.A0.State == EAS_RValue);
+    EXPECT_TRUE(back.A1.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A3.State == EAS_Defaulted);
   }
   {
     SmallVector<Emplaceable, 3> V;
-    V.emplace_back(A0);
+    Emplaceable &back = V.emplace_back(A0);
+    EXPECT_TRUE(&back == &V.back());
     EXPECT_TRUE(V.size() == 1);
-    EXPECT_TRUE(V.back().State == ES_Emplaced);
-    EXPECT_TRUE(V.back().A0.State == EAS_LValue);
-    EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+    EXPECT_TRUE(back.State == ES_Emplaced);
+    EXPECT_TRUE(back.A0.State == EAS_LValue);
+    EXPECT_TRUE(back.A1.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A3.State == EAS_Defaulted);
   }
   {
     SmallVector<Emplaceable, 3> V;
-    V.emplace_back(A0, A1);
+    Emplaceable &back = V.emplace_back(A0, A1);
+    EXPECT_TRUE(&back == &V.back());
     EXPECT_TRUE(V.size() == 1);
-    EXPECT_TRUE(V.back().State == ES_Emplaced);
-    EXPECT_TRUE(V.back().A0.State == EAS_LValue);
-    EXPECT_TRUE(V.back().A1.State == EAS_LValue);
-    EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+    EXPECT_TRUE(back.State == ES_Emplaced);
+    EXPECT_TRUE(back.A0.State == EAS_LValue);
+    EXPECT_TRUE(back.A1.State == EAS_LValue);
+    EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A3.State == EAS_Defaulted);
   }
   {
     SmallVector<Emplaceable, 3> V;
-    V.emplace_back(std::move(A0), std::move(A1));
+    Emplaceable &back = V.emplace_back(std::move(A0), std::move(A1));
+    EXPECT_TRUE(&back == &V.back());
     EXPECT_TRUE(V.size() == 1);
-    EXPECT_TRUE(V.back().State == ES_Emplaced);
-    EXPECT_TRUE(V.back().A0.State == EAS_RValue);
-    EXPECT_TRUE(V.back().A1.State == EAS_RValue);
-    EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
-    EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+    EXPECT_TRUE(back.State == ES_Emplaced);
+    EXPECT_TRUE(back.A0.State == EAS_RValue);
+    EXPECT_TRUE(back.A1.State == EAS_RValue);
+    EXPECT_TRUE(back.A2.State == EAS_Defaulted);
+    EXPECT_TRUE(back.A3.State == EAS_Defaulted);
   }
   {
     SmallVector<Emplaceable, 3> V;
-    V.emplace_back(std::move(A0), A1, std::move(A2), A3);
+    Emplaceable &back = V.emplace_back(std::move(A0), A1, std::move(A2), A3);
+    EXPECT_TRUE(&back == &V.back());
     EXPECT_TRUE(V.size() == 1);
-    EXPECT_TRUE(V.back().State == ES_Emplaced);
-    EXPECT_TRUE(V.back().A0.State == EAS_RValue);
-    EXPECT_TRUE(V.back().A1.State == EAS_LValue);
-    EXPECT_TRUE(V.back().A2.State == EAS_RValue);
-    EXPECT_TRUE(V.back().A3.State == EAS_LValue);
+    EXPECT_TRUE(back.State == ES_Emplaced);
+    EXPECT_TRUE(back.A0.State == EAS_RValue);
+    EXPECT_TRUE(back.A1.State == EAS_LValue);
+    EXPECT_TRUE(back.A2.State == EAS_RValue);
+    EXPECT_TRUE(back.A3.State == EAS_LValue);
   }
   {
     SmallVector<int, 1> V;
diff --git a/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp
index 7675dda..db8d58a 100644
--- a/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SparseBitVectorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/SparseBitVectorTest.cpp - SparseBitVector tests --===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp
index 032990e..54f7bc9 100644
--- a/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SparseMultiSetTest.cpp
@@ -1,9 +1,8 @@
 //===------ ADT/SparseSetTest.cpp - SparseSet unit tests -  -----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp
index 4db7a7d..2b065ea 100644
--- a/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/SparseSetTest.cpp
@@ -1,9 +1,8 @@
 //===------ ADT/SparseSetTest.cpp - SparseSet unit tests -  -----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp b/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp
index 17a5c7f..1b5530f 100644
--- a/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StatisticTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/StatisticTest.cpp - Statistic unit tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp
index 02a45c3..97c91de 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringExtrasTest.cpp
@@ -1,9 +1,8 @@
 //===- StringExtrasTest.cpp - Unit tests for String extras ----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp
index a44bbbf..4038d4d 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringMapTest.cpp
@@ -1,14 +1,12 @@
 //===- llvm/unittest/ADT/StringMapMap.cpp - StringMap unit tests ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/DataTypes.h"
 #include "gtest/gtest.h"
@@ -285,20 +283,6 @@
   EXPECT_EQ(Expected, Keys);
 }
 
-TEST_F(StringMapTest, IterSetKeys) {
-  StringSet<> Set;
-  Set.insert("A");
-  Set.insert("B");
-  Set.insert("C");
-  Set.insert("D");
-
-  auto Keys = to_vector<4>(Set.keys());
-  llvm::sort(Keys);
-
-  SmallVector<StringRef, 4> Expected = {"A", "B", "C", "D"};
-  EXPECT_EQ(Expected, Keys);
-}
-
 // Create a non-default constructable value
 struct StringMapTestStruct {
   StringMapTestStruct(int i) : i(i) {}
diff --git a/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp
index 4087d6c..a45e83c 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringRefTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/StringRefTest.cpp - StringRef unit tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -35,10 +34,6 @@
 // Check that we can't accidentally assign a temporary std::string to a
 // StringRef. (Unfortunately we can't make use of the same thing with
 // constructors.)
-//
-// Disable this check under MSVC; even MSVC 2015 isn't consistent between
-// std::is_assignable and actually writing such an assignment.
-#if !defined(_MSC_VER)
 static_assert(
     !std::is_assignable<StringRef&, std::string>::value,
     "Assigning from prvalue std::string");
@@ -57,8 +52,6 @@
 static_assert(
     std::is_assignable<StringRef&, const char * &>::value,
     "Assigning from lvalue C string");
-#endif
-
 
 namespace {
 TEST(StringRefTest, Construction) {
@@ -1062,4 +1055,6 @@
   EXPECT_EQ(StringRef("Bar"), Strings[1]);
 }
 
+static_assert(is_trivially_copyable<StringRef>::value, "trivially copyable");
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/StringSetTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringSetTest.cpp
new file mode 100644
index 0000000..17bfa1d
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ADT/StringSetTest.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/ADT/StringSetTest.cpp - StringSet unit tests ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringSet.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+
+// Test fixture
+class StringSetTest : public testing::Test {};
+
+TEST_F(StringSetTest, IterSetKeys) {
+  StringSet<> Set;
+  Set.insert("A");
+  Set.insert("B");
+  Set.insert("C");
+  Set.insert("D");
+
+  auto Keys = to_vector<4>(Set.keys());
+  llvm::sort(Keys);
+
+  SmallVector<StringRef, 4> Expected = {"A", "B", "C", "D"};
+  EXPECT_EQ(Expected, Keys);
+}
+
+TEST_F(StringSetTest, InsertAndCountStringMapEntry) {
+  // Test insert(StringMapEntry) and count(StringMapEntry)
+  // which are required for set_difference(StringSet, StringSet).
+  StringSet<> Set;
+  StringMapEntry<StringRef> *Element = StringMapEntry<StringRef>::Create("A");
+  Set.insert(*Element);
+  size_t Count = Set.count(*Element);
+  size_t Expected = 1;
+  EXPECT_EQ(Expected, Count);
+  Element->Destroy();
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp b/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp
index 62d3a31..2ce6cdc 100644
--- a/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/StringSwitchTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/StringSwitchTest.cpp - StringSwitch unit tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/TestGraph.h b/src/llvm-project/llvm/unittests/ADT/TestGraph.h
index 4ddd14c..36d2982 100644
--- a/src/llvm-project/llvm/unittests/ADT/TestGraph.h
+++ b/src/llvm-project/llvm/unittests/ADT/TestGraph.h
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/TestGraph.h - Graph for testing ------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp b/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp
index cc14ccc..c8c00d9 100644
--- a/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/TinyPtrVectorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/TinyPtrVectorTest.cpp ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp b/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp
index bc7f932..37ebe5d 100644
--- a/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/TripleTest.cpp
@@ -1,9 +1,8 @@
 //===----------- Triple.cpp - Triple unit tests ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -253,11 +252,11 @@
   EXPECT_EQ(Triple::UnknownOS, T.getOS());
   EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
 
-  T = Triple("wasm32-unknown-wasi-musl");
+  T = Triple("wasm32-unknown-wasi");
   EXPECT_EQ(Triple::wasm32, T.getArch());
   EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
   EXPECT_EQ(Triple::WASI, T.getOS());
-  EXPECT_EQ(Triple::Musl, T.getEnvironment());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
 
   T = Triple("wasm64-unknown-unknown");
   EXPECT_EQ(Triple::wasm64, T.getArch());
@@ -265,11 +264,11 @@
   EXPECT_EQ(Triple::UnknownOS, T.getOS());
   EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
 
-  T = Triple("wasm64-unknown-wasi-musl");
+  T = Triple("wasm64-unknown-wasi");
   EXPECT_EQ(Triple::wasm64, T.getArch());
   EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
   EXPECT_EQ(Triple::WASI, T.getOS());
-  EXPECT_EQ(Triple::Musl, T.getEnvironment());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
 
   T = Triple("avr-unknown-unknown");
   EXPECT_EQ(Triple::avr, T.getArch());
@@ -553,6 +552,13 @@
   EXPECT_EQ(Triple::OpenEmbedded, T.getVendor());
   EXPECT_EQ(Triple::Linux, T.getOS());
   EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+  EXPECT_TRUE(T.isArch64Bit());
+
+  T = Triple("arm64_32-apple-ios");
+  EXPECT_EQ(Triple::aarch64_32, T.getArch());
+  EXPECT_EQ(Triple::IOS, T.getOS());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+  EXPECT_TRUE(T.isArch32Bit());
 
   T = Triple("huh");
   EXPECT_EQ(Triple::UnknownArch, T.getArch());
@@ -703,6 +709,10 @@
             Triple::normalize("i686-linux")); // i686-pc-linux-gnu
   EXPECT_EQ("arm-none-unknown-eabi",
             Triple::normalize("arm-none-eabi")); // arm-none-eabi
+  EXPECT_EQ("wasm32-unknown-wasi",
+            Triple::normalize("wasm32-wasi")); // wasm32-unknown-wasi
+  EXPECT_EQ("wasm64-unknown-wasi",
+            Triple::normalize("wasm64-wasi")); // wasm64-unknown-wasi
 }
 
 TEST(TripleTest, MutateName) {
@@ -866,11 +876,13 @@
   EXPECT_FALSE(T.isArch16Bit());
   EXPECT_TRUE(T.isArch32Bit());
   EXPECT_FALSE(T.isArch64Bit());
+  EXPECT_TRUE(T.isRISCV());
 
   T.setArch(Triple::riscv64);
   EXPECT_FALSE(T.isArch16Bit());
   EXPECT_FALSE(T.isArch32Bit());
   EXPECT_TRUE(T.isArch64Bit());
+  EXPECT_TRUE(T.isRISCV());
 }
 
 TEST(TripleTest, BitWidthArchVariants) {
@@ -1227,6 +1239,17 @@
   EXPECT_EQ((unsigned)3, Minor);
   EXPECT_EQ((unsigned)0, Micro);
   EXPECT_TRUE(T.isSimulatorEnvironment());
+  EXPECT_FALSE(T.isMacCatalystEnvironment());
+
+  T = Triple("x86_64-apple-ios13.0-macabi");
+  EXPECT_TRUE(T.isiOS());
+  T.getiOSVersion(Major, Minor, Micro);
+  EXPECT_EQ((unsigned)13, Major);
+  EXPECT_EQ((unsigned)0, Minor);
+  EXPECT_EQ((unsigned)0, Micro);
+  EXPECT_TRUE(T.getEnvironment() == Triple::MacABI);
+  EXPECT_TRUE(T.isMacCatalystEnvironment());
+  EXPECT_FALSE(T.isSimulatorEnvironment());
 }
 
 TEST(TripleTest, FileFormat) {
@@ -1247,17 +1270,28 @@
 
   EXPECT_EQ(Triple::Wasm, Triple("wasm32-unknown-unknown").getObjectFormat());
   EXPECT_EQ(Triple::Wasm, Triple("wasm64-unknown-unknown").getObjectFormat());
-  EXPECT_EQ(Triple::Wasm, Triple("wasm32-unknown-wasi-musl").getObjectFormat());
-  EXPECT_EQ(Triple::Wasm, Triple("wasm64-unknown-wasi-musl").getObjectFormat());
+  EXPECT_EQ(Triple::Wasm, Triple("wasm32-wasi").getObjectFormat());
+  EXPECT_EQ(Triple::Wasm, Triple("wasm64-wasi").getObjectFormat());
+  EXPECT_EQ(Triple::Wasm, Triple("wasm32-unknown-wasi").getObjectFormat());
+  EXPECT_EQ(Triple::Wasm, Triple("wasm64-unknown-wasi").getObjectFormat());
 
   EXPECT_EQ(Triple::Wasm,
             Triple("wasm32-unknown-unknown-wasm").getObjectFormat());
   EXPECT_EQ(Triple::Wasm,
             Triple("wasm64-unknown-unknown-wasm").getObjectFormat());
   EXPECT_EQ(Triple::Wasm,
-            Triple("wasm32-unknown-wasi-musl-wasm").getObjectFormat());
+            Triple("wasm32-wasi-wasm").getObjectFormat());
   EXPECT_EQ(Triple::Wasm,
-            Triple("wasm64-unknown-wasi-musl-wasm").getObjectFormat());
+            Triple("wasm64-wasi-wasm").getObjectFormat());
+  EXPECT_EQ(Triple::Wasm,
+            Triple("wasm32-unknown-wasi-wasm").getObjectFormat());
+  EXPECT_EQ(Triple::Wasm,
+            Triple("wasm64-unknown-wasi-wasm").getObjectFormat());
+
+  EXPECT_EQ(Triple::XCOFF, Triple("powerpc-ibm-aix").getObjectFormat());
+  EXPECT_EQ(Triple::XCOFF, Triple("powerpc64-ibm-aix").getObjectFormat());
+  EXPECT_EQ(Triple::XCOFF, Triple("powerpc---xcoff").getObjectFormat());
+  EXPECT_EQ(Triple::XCOFF, Triple("powerpc64---xcoff").getObjectFormat());
 
   Triple MSVCNormalized(Triple::normalize("i686-pc-windows-msvc-elf"));
   EXPECT_EQ(Triple::ELF, MSVCNormalized.getObjectFormat());
@@ -1277,6 +1311,9 @@
 
   T.setObjectFormat(Triple::MachO);
   EXPECT_EQ(Triple::MachO, T.getObjectFormat());
+
+  T.setObjectFormat(Triple::XCOFF);
+  EXPECT_EQ(Triple::XCOFF, T.getObjectFormat());
 }
 
 TEST(TripleTest, NormalizeWindows) {
@@ -1321,6 +1358,8 @@
 
   EXPECT_EQ("i686-pc-windows-elf",
             Triple::normalize("i686-pc-windows-elf-elf"));
+
+  EXPECT_TRUE(Triple("x86_64-pc-win32").isWindowsMSVCEnvironment());
 }
 
 TEST(TripleTest, getARMCPUForArch) {
@@ -1441,6 +1480,10 @@
     EXPECT_EQ(Triple::aarch64, T.getArch());
   }
   {
+    Triple T = Triple("arm64_32");
+    EXPECT_EQ(Triple::aarch64_32, T.getArch());
+  }
+  {
     Triple T = Triple("aarch64");
     EXPECT_EQ(Triple::aarch64, T.getArch());
   }
diff --git a/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp b/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp
index 950eda2..a717036 100644
--- a/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/TwineTest.cpp
@@ -1,9 +1,8 @@
 //===- TwineTest.cpp - Twine unit tests -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp b/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp
index 43db648..56cf85a 100644
--- a/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp
+++ b/src/llvm-project/llvm/unittests/ADT/VariadicFunctionTest.cpp
@@ -1,9 +1,8 @@
 //===----------- VariadicFunctionTest.cpp - VariadicFunction unit tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp b/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp
index 42a4210..80bdcf7 100644
--- a/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/AliasAnalysisTest.cpp
@@ -1,9 +1,8 @@
 //===--- AliasAnalysisTest.cpp - Mixed TBAA unit tests --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -86,7 +85,8 @@
 
   bool invalidate(Function &, const PreservedAnalyses &) { return false; }
 
-  AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
+  AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+                    AAQueryInfo &AAQI) {
     CB();
     return MayAlias;
   }
@@ -167,7 +167,7 @@
   // Setup function.
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(C), std::vector<Type *>(), false);
-  auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  auto *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   auto *BB = BasicBlock::Create(C, "entry", F);
   auto IntType = Type::getInt32Ty(C);
   auto PtrType = Type::getInt32PtrTy(C);
@@ -175,7 +175,7 @@
   auto *Addr = ConstantPointerNull::get(PtrType);
 
   auto *Store1 = new StoreInst(Value, Addr, BB);
-  auto *Load1 = new LoadInst(Addr, "load", BB);
+  auto *Load1 = new LoadInst(IntType, Addr, "load", BB);
   auto *Add1 = BinaryOperator::CreateAdd(Value, Value, "add", BB);
   auto *VAArg1 = new VAArgInst(Addr, PtrType, "vaarg", BB);
   auto *CmpXChg1 = new AtomicCmpXchgInst(
diff --git a/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp b/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp
index 57d21e2..77a5ac4 100644
--- a/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/AliasSetTrackerTest.cpp
@@ -1,9 +1,8 @@
 //=======- AliasSetTrackerTest.cpp - Unit test for the Alias Set Tracker  -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp b/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp
index fc52aff..f69d2d1 100644
--- a/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/BasicAliasAnalysisTest.cpp
@@ -1,9 +1,8 @@
 //===- BasicAliasAnalysisTest.cpp - Unit tests for BasicAA ----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -45,17 +44,19 @@
     DominatorTree DT;
     AssumptionCache AC;
     BasicAAResult BAA;
+    AAQueryInfo AAQI;
 
     TestAnalyses(BasicAATest &Test)
-        : DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT) {}
+        : DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT),
+          AAQI() {}
   };
 
   llvm::Optional<TestAnalyses> Analyses;
 
-  BasicAAResult &setupAnalyses() {
+  TestAnalyses &setupAnalyses() {
     assert(F);
     Analyses.emplace(*this);
-    return Analyses->BAA;
+    return Analyses.getValue();
   }
 
 public:
@@ -84,15 +85,17 @@
   GlobalPtr->setLinkage(GlobalValue::LinkageTypes::InternalLinkage);
   GlobalPtr->setInitializer(B.getInt8(0));
 
-  BasicAAResult &BasicAA = setupAnalyses();
+  auto &AllAnalyses = setupAnalyses();
+  BasicAAResult &BasicAA = AllAnalyses.BAA;
+  AAQueryInfo &AAQI = AllAnalyses.AAQI;
   ASSERT_EQ(
       BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::precise(4)),
-                    MemoryLocation(GlobalPtr, LocationSize::precise(1))),
+                    MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
       AliasResult::NoAlias);
 
   ASSERT_EQ(
       BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::upperBound(4)),
-                    MemoryLocation(GlobalPtr, LocationSize::precise(1))),
+                    MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
       AliasResult::MayAlias);
 }
 
@@ -109,16 +112,20 @@
   Value *ArbitraryI32 = F->arg_begin();
   AllocaInst *I8 = B.CreateAlloca(B.getInt8Ty(), B.getInt32(2));
   auto *I8AtUncertainOffset =
-      cast<GetElementPtrInst>(B.CreateGEP(I8, ArbitraryI32));
+      cast<GetElementPtrInst>(B.CreateGEP(B.getInt8Ty(), I8, ArbitraryI32));
 
-  BasicAAResult &BasicAA = setupAnalyses();
+  auto &AllAnalyses = setupAnalyses();
+  BasicAAResult &BasicAA = AllAnalyses.BAA;
+  AAQueryInfo &AAQI = AllAnalyses.AAQI;
   ASSERT_EQ(BasicAA.alias(
                 MemoryLocation(I8, LocationSize::precise(2)),
-                MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
+                MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
+                AAQI),
             AliasResult::PartialAlias);
 
   ASSERT_EQ(BasicAA.alias(
                 MemoryLocation(I8, LocationSize::upperBound(2)),
-                MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1))),
+                MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
+                AAQI),
             AliasResult::MayAlias);
 }
diff --git a/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp
index cc05306..2aeba94 100644
--- a/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp
@@ -1,13 +1,13 @@
 //===- BlockFrequencyInfoTest.cpp - BlockFrequencyInfo unit tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
 #include "llvm/Analysis/BranchProbabilityInfo.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/AsmParser/Parser.h"
@@ -91,5 +91,8 @@
   EXPECT_EQ(BFI.getBlockFreq(BB3).getFrequency(), BB3Freq);
 }
 
+static_assert(is_trivially_copyable<bfi_detail::BlockMass>::value,
+              "trivially copyable");
+
 } // end anonymous namespace
 } // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp
index 529af5c..0166163 100644
--- a/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/BranchProbabilityInfoTest.cpp
@@ -1,9 +1,8 @@
 //===- BranchProbabilityInfoTest.cpp - BranchProbabilityInfo unit tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp
index d7f14c3..107bd08 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CFGTest.cpp
@@ -1,13 +1,13 @@
 //===- CFGTest.cpp - CFG tests --------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/CFG.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/Dominators.h"
@@ -58,24 +58,32 @@
       report_fatal_error("@test must have an instruction %A");
     if (B == nullptr)
       report_fatal_error("@test must have an instruction %B");
+
+    assert(ExclusionSet.empty());
+    for (auto I = F->begin(), E = F->end(); I != E; ++I) {
+      if (I->hasName() && I->getName().startswith("excluded"))
+        ExclusionSet.insert(&*I);
+    }
   }
 
   void ExpectPath(bool ExpectedResult) {
     static char ID;
     class IsPotentiallyReachableTestPass : public FunctionPass {
      public:
-      IsPotentiallyReachableTestPass(bool ExpectedResult,
-                                     Instruction *A, Instruction *B)
-          : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B) {}
+       IsPotentiallyReachableTestPass(bool ExpectedResult, Instruction *A,
+                                      Instruction *B,
+                                      SmallPtrSet<BasicBlock *, 4> ExclusionSet)
+           : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B),
+             ExclusionSet(ExclusionSet) {}
 
-      static int initialize() {
-        PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
-                                    "", &ID, nullptr, true, true);
-        PassRegistry::getPassRegistry()->registerPass(*PI, false);
-        initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
-        initializeDominatorTreeWrapperPassPass(
-            *PassRegistry::getPassRegistry());
-        return 0;
+       static int initialize() {
+         PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass", "",
+                                     &ID, nullptr, true, true);
+         PassRegistry::getPassRegistry()->registerPass(*PI, false);
+         initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
+         initializeDominatorTreeWrapperPassPass(
+             *PassRegistry::getPassRegistry());
+         return 0;
       }
 
       void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -91,22 +99,26 @@
         LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
         DominatorTree *DT =
             &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-        EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr),
+        EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, nullptr),
                   ExpectedResult);
-        EXPECT_EQ(isPotentiallyReachable(A, B, DT, nullptr), ExpectedResult);
-        EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, LI), ExpectedResult);
-        EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult);
+        EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, nullptr),
+                  ExpectedResult);
+        EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, nullptr, LI),
+                  ExpectedResult);
+        EXPECT_EQ(isPotentiallyReachable(A, B, &ExclusionSet, DT, LI),
+                  ExpectedResult);
         return false;
       }
       bool ExpectedResult;
       Instruction *A, *B;
+      SmallPtrSet<BasicBlock *, 4> ExclusionSet;
     };
 
     static int initialize = IsPotentiallyReachableTestPass::initialize();
     (void)initialize;
 
     IsPotentiallyReachableTestPass *P =
-        new IsPotentiallyReachableTestPass(ExpectedResult, A, B);
+        new IsPotentiallyReachableTestPass(ExpectedResult, A, B, ExclusionSet);
     legacy::PassManager PM;
     PM.add(P);
     PM.run(*M);
@@ -115,6 +127,7 @@
   LLVMContext Context;
   std::unique_ptr<Module> M;
   Instruction *A, *B;
+  SmallPtrSet<BasicBlock *, 4> ExclusionSet;
 };
 
 }
@@ -386,3 +399,109 @@
   S[0] = OldBB;
   ExpectPath(true);
 }
+
+TEST_F(IsPotentiallyReachableTest, UnreachableFromEntryTest) {
+  ParseAssembly("define void @test() {\n"
+                "entry:\n"
+                "  %A = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "not.reachable:\n"
+                "  %B = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "}");
+  ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest1) {
+  ParseAssembly("define void @test() {\n"
+                "entry:\n"
+                "  ret void\n"
+                "not.reachable.1:\n"
+                "  %A = bitcast i8 undef to i8\n"
+                "  br label %not.reachable.2\n"
+                "not.reachable.2:\n"
+                "  %B = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "}");
+  ExpectPath(true);
+}
+
+TEST_F(IsPotentiallyReachableTest, UnreachableBlocksTest2) {
+  ParseAssembly("define void @test() {\n"
+                "entry:\n"
+                "  ret void\n"
+                "not.reachable.1:\n"
+                "  %B = bitcast i8 undef to i8\n"
+                "  br label %not.reachable.2\n"
+                "not.reachable.2:\n"
+                "  %A = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "}");
+  ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, SimpleExclusionTest) {
+  ParseAssembly("define void @test() {\n"
+                "entry:\n"
+                "  %A = bitcast i8 undef to i8\n"
+                "  br label %excluded\n"
+                "excluded:\n"
+                "  br label %exit\n"
+                "exit:\n"
+                "  %B = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "}");
+  ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, DiamondExcludedTest) {
+  ParseAssembly("declare i1 @switch()\n"
+                "\n"
+                "define void @test() {\n"
+                "entry:\n"
+                "  %x = call i1 @switch()\n"
+                "  %A = bitcast i8 undef to i8\n"
+                "  br i1 %x, label %excluded.1, label %excluded.2\n"
+                "excluded.1:\n"
+                "  br label %exit\n"
+                "excluded.2:\n"
+                "  br label %exit\n"
+                "exit:\n"
+                "  %B = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "}");
+  ExpectPath(false);
+}
+
+TEST_F(IsPotentiallyReachableTest, DiamondOneSideExcludedTest) {
+  ParseAssembly("declare i1 @switch()\n"
+                "\n"
+                "define void @test() {\n"
+                "entry:\n"
+                "  %x = call i1 @switch()\n"
+                "  %A = bitcast i8 undef to i8\n"
+                "  br i1 %x, label %excluded, label %diamond\n"
+                "excluded:\n"
+                "  br label %exit\n"
+                "diamond:\n"
+                "  br label %exit\n"
+                "exit:\n"
+                "  %B = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "}");
+  ExpectPath(true);
+}
+
+TEST_F(IsPotentiallyReachableTest, UnreachableToReachable) {
+  ParseAssembly("define void @test() {\n"
+                "entry:\n"
+                "  br label %exit\n"
+                "unreachableblock:\n"
+                "  %A = bitcast i8 undef to i8\n"
+                "  br label %exit\n"
+                "exit:\n"
+                "  %B = bitcast i8 undef to i8\n"
+                "  ret void\n"
+                "}");
+  ExpectPath(true);
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
index 60da2bb..f1ed35d 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
@@ -1,9 +1,8 @@
 //===- CGSCCPassManagerTest.cpp -------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -1256,26 +1255,30 @@
   MPM.run(*M, MAM);
 
   // We run over four SCCs the first time. But then we split an SCC into three.
-  // And then we merge those three back into one.
-  EXPECT_EQ(4 + 3 + 1, SCCAnalysisRuns);
+  // And then we merge those three back into one. However, this also
+  // invalidates all three SCCs further down in the PO walk.
+  EXPECT_EQ(4 + 3 + 1 + 3, SCCAnalysisRuns);
   // The module analysis pass should be run three times.
   EXPECT_EQ(3, ModuleAnalysisRuns);
   // We run over four SCCs the first time. Then over the two new ones. Then the
   // entire module is invalidated causing a full run over all seven. Then we
-  // fold three SCCs back to one, and then run over the whole module again.
-  EXPECT_EQ(4 + 2 + 7 + 1 + 4, IndirectSCCAnalysisRuns);
-  EXPECT_EQ(4 + 2 + 7 + 1 + 4, DoublyIndirectSCCAnalysisRuns);
+  // fold three SCCs back to one, re-compute for it and the two SCCs above it
+  // in the graph, and then run over the whole module again.
+  EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, IndirectSCCAnalysisRuns);
+  EXPECT_EQ(4 + 2 + 7 + 1 + 3 + 4, DoublyIndirectSCCAnalysisRuns);
 
   // First we run over all six functions. Then we re-run it over three when we
   // split their SCCs. Then we re-run over the whole module. Then we re-run
-  // over three functions merged back into a single SCC, and then over the
-  // whole module again.
-  EXPECT_EQ(6 + 3 + 6 + 3 + 6, FunctionAnalysisRuns);
+  // over three functions merged back into a single SCC, then those three
+  // functions again, the two functions in SCCs above it in the graph, and then
+  // over the whole module again.
+  EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, FunctionAnalysisRuns);
 
   // Re run the function analysis over the entire module, and then re-run it
   // over the `(h3, h1, h2)` SCC due to invalidation. Then we re-run it over
   // the entire module, then the three functions merged back into a single SCC,
-  // and then over the whole module.
-  EXPECT_EQ(6 + 3 + 6 + 3 + 6, IndirectFunctionAnalysisRuns);
+  // those three functions again, then the two functions in SCCs above it in
+  // the graph, and then over the whole module.
+  EXPECT_EQ(6 + 3 + 6 + 3 + 3 + 2 + 6, IndirectFunctionAnalysisRuns);
 }
 }
diff --git a/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt b/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt
index 563b48d..a1858d2 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Analysis/CMakeLists.txt
@@ -16,8 +16,9 @@
   CFGTest.cpp
   CGSCCPassManagerTest.cpp
   DivergenceAnalysisTest.cpp
+  DomTreeUpdaterTest.cpp
   GlobalsModRefTest.cpp
-  ValueLatticeTest.cpp
+  IVDescriptorsTest.cpp
   LazyCallGraphTest.cpp
   LoopInfoTest.cpp
   MemoryBuiltinsTest.cpp
@@ -31,5 +32,7 @@
   TargetLibraryInfoTest.cpp
   TBAATest.cpp
   UnrollAnalyzerTest.cpp
+  ValueLatticeTest.cpp
   ValueTrackingTest.cpp
+  VectorUtilsTest.cpp
   )
diff --git a/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp
index 2d4e63f..0060d2c4 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CallGraphTest.cpp
@@ -1,9 +1,8 @@
 //=======- CallGraphTest.cpp - Unit tests for the CG analysis -------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp b/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp
index ee6e010..86a0aa1 100644
--- a/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/CaptureTrackingTest.cpp
@@ -1,9 +1,8 @@
 //=======- CaptureTrackingTest.cpp - Unit test for the Capture Tracking ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp b/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp
index 97dbd18..9416e59 100644
--- a/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/DivergenceAnalysisTest.cpp
@@ -1,9 +1,8 @@
 //===- DivergenceAnalysisTest.cpp - DivergenceAnalysis unit tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -79,7 +78,7 @@
   IntegerType *IntTy = IntegerType::getInt32Ty(Context);
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), {IntTy}, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
   ReturnInst::Create(Context, nullptr, BB);
 
diff --git a/src/llvm-project/llvm/unittests/IR/DomTreeUpdaterTest.cpp b/src/llvm-project/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
similarity index 85%
rename from src/llvm-project/llvm/unittests/IR/DomTreeUpdaterTest.cpp
rename to src/llvm-project/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
index db2bb80..4a5e2d7 100644
--- a/src/llvm-project/llvm/unittests/IR/DomTreeUpdaterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
@@ -1,13 +1,12 @@
-//==- llvm/unittests/IR/DomTreeUpdaterTest.cpp - DomTreeUpdater unit tests ===//
+//===- DomTreeUpdaterTest.cpp - DomTreeUpdater unit tests -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/DomTreeUpdater.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
 #include "llvm/Analysis/PostDominators.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/Constants.h"
@@ -72,8 +71,9 @@
   SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
   ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";
 
-  DTU.insertEdgeRelaxed(BB0, BB0);
-  DTU.deleteEdgeRelaxed(BB0, BB0);
+  DTU.applyUpdatesPermissive(
+      {{DominatorTree::Insert, BB0, BB0}, {DominatorTree::Delete, BB0, BB0}});
+  ASSERT_FALSE(DTU.hasPendingUpdates());
 
   // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
   // entries are discarded.
@@ -102,13 +102,13 @@
   // queued for deletion.
   ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
   EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
-  DTU.applyUpdates(Updates, /*ForceRemoveDuplicates*/ true);
+  DTU.applyUpdatesPermissive(Updates);
   ASSERT_FALSE(DTU.hasPendingUpdates());
 
   // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
-  DTU.insertEdgeRelaxed(BB1, BB2);
   // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
-  DTU.deleteEdgeRelaxed(BB0, BB1);
+  DTU.applyUpdatesPermissive(
+      {{DominatorTree::Insert, BB1, BB2}, {DominatorTree::Delete, BB0, BB1}});
 
   // DTU working with Eager UpdateStrategy does not need to flush.
   ASSERT_TRUE(DT.verify());
@@ -183,7 +183,7 @@
   EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
   EXPECT_TRUE(&F->getEntryBlock() == NewEntry);
 
-  DTU.insertEdgeRelaxed(NewEntry, BB0);
+  DTU.applyUpdates({{DominatorTree::Insert, NewEntry, BB0}});
 
   // Changing the Entry BB requires a full recalculation of DomTree.
   DTU.recalculate(*F);
@@ -252,7 +252,7 @@
   BasicBlock *BB3 = &*FI++;
 
   // Test discards of self-domination update.
-  DTU.deleteEdge(BB0, BB0);
+  DTU.applyUpdatesPermissive({{DominatorTree::Insert, BB0, BB0}});
   ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
 
   // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
@@ -275,7 +275,7 @@
 
   // Verify. Updates to DTU must be applied *after* all changes to the CFG
   // (including block deletion).
-  DTU.applyUpdates(Updates);
+  DTU.applyUpdatesPermissive(Updates);
   ASSERT_TRUE(DTU.getDomTree().verify());
 
   // Deletion of a BasicBlock is an immediate event. We remove all uses to the
@@ -359,8 +359,10 @@
   //   +-> succ
   //
   // While the final CFG form is functionally identical the updates to
-  // DTU are not. In the first case we must have DTU.insertEdge(Pred1, Succ)
-  // while in the latter case we must *NOT* have DTU.insertEdge(Pred1, Succ).
+  // DTU are not. In the first case we must have
+  // DTU.applyUpdates({{DominatorTree::Insert, Pred1, Succ}}) while in
+  // the latter case we must *NOT* have
+  // DTU.applyUpdates({{DominatorTree::Insert, Pred1, Succ}}).
 
   // CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to
   // remove bb2.
@@ -380,9 +382,9 @@
         BasicBlocks.end());
   };
   ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
-  // Remove bb2 from F. This has to happen before the call to applyUpdates() for
-  // DTU to detect there is no longer an edge between bb2 -> bb3. The deleteBB()
-  // method converts bb2's TI into "unreachable".
+  // Remove bb2 from F. This has to happen before the call to
+  // applyUpdates() for DTU to detect there is no longer an edge between
+  // bb2 -> bb3. The deleteBB() method converts bb2's TI into "unreachable".
   ASSERT_FALSE(isa<UnreachableInst>(BB2->getTerminator()));
   EXPECT_FALSE(DTU.isBBPendingDeletion(BB2));
   DTU.callbackDeleteBB(BB2, Eraser);
@@ -403,9 +405,9 @@
   BranchInst::Create(BB3, BB0);
   EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
 
-  // Remove bb1 from F. This has to happen before the call to applyUpdates() for
-  // DTU to detect there is no longer an edge between bb1 -> bb3. The deleteBB()
-  // method converts bb1's TI into "unreachable".
+  // Remove bb1 from F. This has to happen before the call to
+  // applyUpdates() for DTU to detect there is no longer an edge between
+  // bb1 -> bb3. The deleteBB() method converts bb1's TI into "unreachable".
   ASSERT_FALSE(isa<UnreachableInst>(BB1->getTerminator()));
   EXPECT_FALSE(DTU.isBBPendingDeletion(BB1));
   DTU.callbackDeleteBB(BB1, Eraser);
@@ -413,14 +415,14 @@
   ASSERT_TRUE(isa<UnreachableInst>(BB1->getTerminator()));
   EXPECT_EQ(BB1->getParent(), F);
 
-  // Update the DTU. In this case we don't call DTU.insertEdge(BB0, BB3) because
-  // the edge previously existed at the start of this test when DT was first
-  // created.
+  // Update the DTU. In this case we don't submit {DominatorTree::Insert, BB0,
+  // BB3} because the edge previously existed at the start of this test when DT
+  // was first created.
   Updates.push_back({DominatorTree::Delete, BB0, BB1});
   Updates.push_back({DominatorTree::Delete, BB1, BB3});
 
   // Verify everything.
-  DTU.applyUpdates(Updates);
+  DTU.applyUpdatesPermissive(Updates);
   ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
   DTU.flush();
   ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(0));
@@ -468,7 +470,7 @@
   BasicBlock *BB2 = &*FI++;
   BasicBlock *BB3 = &*FI++;
   // Test discards of self-domination update.
-  DTU.deleteEdge(BB0, BB0);
+  DTU.applyUpdates({{DominatorTree::Delete, BB0, BB0}});
 
   // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
   // entries are discarded.
@@ -505,7 +507,7 @@
 
   // Verify. Updates to DTU must be applied *after* all changes to the CFG
   // (including block deletion).
-  DTU.applyUpdates(Updates);
+  DTU.applyUpdatesPermissive(Updates);
   ASSERT_TRUE(DTU.getDomTree().verify());
   ASSERT_TRUE(DTU.hasPendingUpdates());
   ASSERT_TRUE(DTU.hasPendingPostDomTreeUpdates());
@@ -559,7 +561,7 @@
   // Insert the new edge between new_entry -> bb0. Without this the
   // recalculate() call below will not actually recalculate the DT as there
   // are no changes pending and no blocks deleted.
-  DTU.insertEdge(NewEntry, BB0);
+  DTU.applyUpdates({{DominatorTree::Insert, NewEntry, BB0}});
 
   // Changing the Entry BB requires a full recalculation.
   DTU.recalculate(*F);
@@ -644,8 +646,7 @@
   SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
   ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";
 
-  // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
-  // entries are discarded.
+  // Delete edge bb0 -> bb3.
   std::vector<DominatorTree::UpdateType> Updates;
   Updates.reserve(1);
   Updates.push_back({DominatorTree::Delete, BB0, BB3});
@@ -690,7 +691,7 @@
       ++i;
   }
 
-  DTU.applyUpdates(Updates);
+  DTU.applyUpdatesPermissive(Updates);
   // flush PostDomTree
   ASSERT_TRUE(DTU.getPostDomTree().verify());
   ASSERT_FALSE(DTU.hasPendingPostDomTreeUpdates());
@@ -725,3 +726,69 @@
   DTU.recalculate(*F);
   ASSERT_FALSE(DTU.hasPendingDeletedBB());
 }
+
+TEST(DomTreeUpdater, LazyUpdateDeduplicationTest) {
+  StringRef FuncName = "f";
+  StringRef ModuleString = R"(
+                           define i32 @f() {
+                           bb0:
+                              br label %bb1
+                           bb1:
+                              ret i32 1
+                           bb2:
+                              ret i32 1
+                           }
+                           )";
+  // Make the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
+  Function *F = M->getFunction(FuncName);
+
+  // Make the DTU.
+  DominatorTree DT(*F);
+  DomTreeUpdater DTU(&DT, nullptr, DomTreeUpdater::UpdateStrategy::Lazy);
+  ASSERT_TRUE(DTU.getDomTree().verify());
+
+  Function::iterator FI = F->begin();
+  BasicBlock *BB0 = &*FI++;
+  BasicBlock *BB1 = &*FI++;
+  BasicBlock *BB2 = &*FI++;
+
+  // CFG Change: remove bb0 -> bb1 and add back bb0 -> bb1.
+  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+  BB0->getTerminator()->eraseFromParent();
+  BranchInst::Create(BB1, BB0);
+  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+
+  // Update the DTU and simulate duplicates.
+  DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1},
+                              {DominatorTree::Delete, BB0, BB1},
+                              {DominatorTree::Insert, BB0, BB1},
+                              {DominatorTree::Insert, BB0, BB1},
+                              {DominatorTree::Insert, BB0, BB1}});
+
+  // The above operations result in a no-op.
+  ASSERT_FALSE(DTU.hasPendingUpdates());
+
+  // Update the DTU. Simulate an invalid update.
+  DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1}});
+  ASSERT_FALSE(DTU.hasPendingUpdates());
+
+  // CFG Change: remove bb0 -> bb1.
+  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+  BB0->getTerminator()->eraseFromParent();
+
+  // Update the DTU and simulate invalid updates.
+  DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1},
+                              {DominatorTree::Insert, BB0, BB1},
+                              {DominatorTree::Delete, BB0, BB1},
+                              {DominatorTree::Insert, BB0, BB1},
+                              {DominatorTree::Insert, BB0, BB1}});
+  ASSERT_TRUE(DTU.hasPendingUpdates());
+
+  // CFG Change: add bb0 -> bb2.
+  BranchInst::Create(BB2, BB0);
+  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
+  DTU.applyUpdates({{DominatorTree::Insert, BB0, BB2}});
+  ASSERT_TRUE(DTU.getDomTree().verify());
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp b/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp
index 323edc2..dfc8e1e 100644
--- a/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/GlobalsModRefTest.cpp
@@ -1,9 +1,8 @@
 //===--- GlobalsModRefTest.cpp - Mixed TBAA unit tests --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/IVDescriptorsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/IVDescriptorsTest.cpp
new file mode 100644
index 0000000..cba45a9
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Analysis/IVDescriptorsTest.cpp
@@ -0,0 +1,100 @@
+//===- IVDescriptorsTest.cpp - IVDescriptors unit tests -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/IVDescriptors.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+/// Build the loop info and scalar evolution for the function and run the Test.
+static void runWithLoopInfoAndSE(
+    Module &M, StringRef FuncName,
+    function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE)> Test) {
+  auto *F = M.getFunction(FuncName);
+  ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
+
+  TargetLibraryInfoImpl TLII;
+  TargetLibraryInfo TLI(TLII);
+  AssumptionCache AC(*F);
+  DominatorTree DT(*F);
+  LoopInfo LI(DT);
+  ScalarEvolution SE(*F, TLI, AC, DT, LI);
+
+  Test(*F, LI, SE);
+}
+
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+  SMDiagnostic Err;
+  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+  if (!Mod)
+    Err.print("IVDescriptorsTests", errs());
+  return Mod;
+}
+
+// This tests that IVDescriptors can obtain the induction binary operator for
+// integer induction variables. And hasUnsafeAlgebra() and
+// getUnsafeAlgebraInst() correctly return the expected behavior, i.e. no unsafe
+// algebra.
+TEST(IVDescriptorsTest, LoopWithSingleLatch) {
+  // Parse the module.
+  LLVMContext Context;
+
+  std::unique_ptr<Module> M = parseIR(
+    Context,
+    R"(define void @foo(i32* %A, i32 %ub) {
+entry:
+  br label %for.body
+for.body:
+  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %idxprom = sext i32 %i to i64
+  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
+  store i32 %i, i32* %arrayidx, align 4
+  %inc = add nsw i32 %i, 1
+  %cmp = icmp slt i32 %inc, %ub
+  br i1 %cmp, label %for.body, label %for.exit
+for.exit:
+  br label %for.end
+for.end:
+  ret void
+})"
+    );
+
+  runWithLoopInfoAndSE(
+      *M, "foo", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+        Function::iterator FI = F.begin();
+        // First basic block is entry - skip it.
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+        PHINode *Inst_i = dyn_cast<PHINode>(&Header->front());
+        assert(Inst_i->getName() == "i");
+        InductionDescriptor IndDesc;
+        bool IsInductionPHI =
+            InductionDescriptor::isInductionPHI(Inst_i, L, &SE, IndDesc);
+        EXPECT_TRUE(IsInductionPHI);
+        Instruction *Inst_inc = nullptr;
+        BasicBlock::iterator BBI = Header->begin();
+        do {
+          if ((&*BBI)->getName() == "inc")
+            Inst_inc = &*BBI;
+          ++BBI;
+        } while (!Inst_inc);
+        assert(Inst_inc->getName() == "inc");
+        EXPECT_EQ(IndDesc.getInductionBinOp(), Inst_inc);
+        EXPECT_FALSE(IndDesc.hasUnsafeAlgebra());
+        EXPECT_EQ(IndDesc.getUnsafeAlgebraInst(), nullptr);
+      });
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp b/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp
index 5e6dd1a..1a7bcc61 100644
--- a/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/LazyCallGraphTest.cpp
@@ -1,9 +1,8 @@
 //===- LazyCallGraphTest.cpp - Unit tests for the lazy CG analysis --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -1978,6 +1977,35 @@
   EXPECT_TRUE(GRC.isParentOf(FRC));
 }
 
+// Test that a blockaddress that refers to itself creates no new RefSCC
+// connections. https://bugs.llvm.org/show_bug.cgi?id=40722
+TEST(LazyCallGraphTest, HandleBlockAddress2) {
+  LLVMContext Context;
+  std::unique_ptr<Module> M =
+      parseAssembly(Context, "define void @f() {\n"
+                             "  ret void\n"
+                             "}\n"
+                             "define void @g(i8** %ptr) {\n"
+                             "bb:\n"
+                             "  store i8* blockaddress(@g, %bb), i8** %ptr\n"
+                             "  ret void\n"
+                             "}\n");
+  LazyCallGraph CG = buildCG(*M);
+
+  CG.buildRefSCCs();
+  auto I = CG.postorder_ref_scc_begin();
+  LazyCallGraph::RefSCC &GRC = *I++;
+  LazyCallGraph::RefSCC &FRC = *I++;
+  EXPECT_EQ(CG.postorder_ref_scc_end(), I);
+
+  LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
+  LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
+  EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
+  EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
+  EXPECT_FALSE(GRC.isParentOf(FRC));
+  EXPECT_FALSE(FRC.isParentOf(GRC));
+}
+
 TEST(LazyCallGraphTest, ReplaceNodeFunction) {
   LLVMContext Context;
   // A graph with several different kinds of edges pointing at a particular
diff --git a/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp
index 9a59fc8..4f0047f 100644
--- a/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/LoopInfoTest.cpp
@@ -1,13 +1,16 @@
 //===- LoopInfoTest.cpp - LoopInfo unit tests -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/Support/SourceMgr.h"
@@ -27,6 +30,26 @@
   Test(*F, LI);
 }
 
+/// Build the loop info and scalar evolution for the function and run the Test.
+static void runWithLoopInfoPlus(
+    Module &M, StringRef FuncName,
+    function_ref<void(Function &F, LoopInfo &LI, ScalarEvolution &SE,
+                      PostDominatorTree &PDT)>
+        Test) {
+  auto *F = M.getFunction(FuncName);
+  ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
+
+  TargetLibraryInfoImpl TLII;
+  TargetLibraryInfo TLI(TLII);
+  AssumptionCache AC(*F);
+  DominatorTree DT(*F);
+  LoopInfo LI(DT);
+  ScalarEvolution SE(*F, TLI, AC, DT, LI);
+
+  PostDominatorTree PDT(*F);
+  Test(*F, LI, SE, PDT);
+}
+
 static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
                                               const char *ModuleStr) {
   SMDiagnostic Err;
@@ -211,3 +234,968 @@
   EXPECT_EQ(&L_0_1, ReverseSiblingPreorder[6]);
   EXPECT_EQ(&L_0_0, ReverseSiblingPreorder[7]);
 }
+
+TEST(LoopInfoTest, CanonicalLoop) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp slt i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopWithInverseGuardSuccs) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp sge i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.end, label %for.preheader\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp slt i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopWithSwappedGuardCmp) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp sgt i32 %ub, 0\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp sge i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.exit, label %for.body\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopWithInverseLatchSuccs) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp sge i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.exit, label %for.body\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopWithLatchCmpNE) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp ne i32 %i, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopWithGuardCmpSLE) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %ubPlusOne = add i32 %ub, 1\n"
+      "  %guardcmp = icmp sle i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp ne i32 %i, %ubPlusOne\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ubPlusOne");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopNonConstantStep) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub, i32 %step) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = zext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, %step\n"
+      "  %cmp = icmp slt i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        EXPECT_EQ(Bounds->getStepValue()->getName(), "step");
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(), Loop::LoopBounds::Direction::Unknown);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopUnsignedBounds) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp ult i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = zext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add i32 %i, 1\n"
+      "  %cmp = icmp ult i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_ULT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, DecreasingLoop) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ %ub, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = sub nsw i32 %i, 1\n"
+      "  %cmp = icmp sgt i32 %inc, 0\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        EXPECT_EQ(Bounds->getInitialIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_EQ(StepValue, nullptr);
+        ConstantInt *FinalIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getFinalIVValue());
+        EXPECT_TRUE(FinalIVValue && FinalIVValue->isZero());
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SGT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Decreasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, CannotFindDirection) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub, i32 %step) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, %step\n"
+      "  %cmp = icmp ne i32 %i, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(*M, "foo",
+                      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+                          PostDominatorTree &PDT) {
+                        Function::iterator FI = F.begin();
+                        // First two basic block are entry and for.preheader
+                        // - skip them.
+                        ++FI;
+                        BasicBlock *Header = &*(++FI);
+                        assert(Header->getName() == "for.body");
+                        Loop *L = LI.getLoopFor(Header);
+                        EXPECT_NE(L, nullptr);
+
+                        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+                        EXPECT_NE(Bounds, None);
+                        ConstantInt *InitialIVValue =
+                            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+                        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+                        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+                        EXPECT_EQ(Bounds->getStepValue()->getName(), "step");
+                        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+                        EXPECT_EQ(Bounds->getCanonicalPredicate(),
+                                  ICmpInst::BAD_ICMP_PREDICATE);
+                        EXPECT_EQ(Bounds->getDirection(),
+                                  Loop::LoopBounds::Direction::Unknown);
+                        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+                      });
+}
+
+TEST(LoopInfoTest, ZextIndVar) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %indvars.iv = phi i64 [ 0, %for.preheader ], [ %indvars.iv.next, %for.body ]\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %wide.trip.count = zext i32 %ub to i64\n"
+      "  %exitcond = icmp ne i64 %indvars.iv.next, %wide.trip.count\n"
+      "  br i1 %exitcond, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "indvars.iv.next");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "wide.trip.count");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_NE);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "indvars.iv");
+      });
+}
+
+TEST(LoopInfoTest, UnguardedLoop) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp slt i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First basic block is entry - skip it.
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, UnguardedLoopWithControlFlow) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub, i1 %cond) {\n"
+      "entry:\n"
+      "  br i1 %cond, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp slt i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, LoopNest) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.outer.preheader, label %for.end\n"
+      "for.outer.preheader:\n"
+      "  br label %for.outer\n"
+      "for.outer:\n"
+      "  %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]\n"
+      "  br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch\n"
+      "for.inner.preheader:\n"
+      "  br label %for.inner\n"
+      "for.inner:\n"
+      "  %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp slt i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.inner, label %for.inner.exit\n"
+      "for.inner.exit:\n"
+      "  br label %for.outer.latch\n"
+      "for.outer.latch:\n"
+      "  %inc.outer = add nsw i32 %j, 1\n"
+      "  %cmp.outer = icmp slt i32 %inc.outer, %ub\n"
+      "  br i1 %cmp.outer, label %for.outer, label %for.outer.exit\n"
+      "for.outer.exit:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.outer.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.outer");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc.outer");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "j");
+
+        // Next two basic blocks are for.outer and for.inner.preheader - skip
+        // them.
+        ++FI;
+        Header = &*(++FI);
+        assert(Header->getName() == "for.inner");
+        L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> InnerBounds = L->getBounds(SE);
+        EXPECT_NE(InnerBounds, None);
+        InitialIVValue =
+            dyn_cast<ConstantInt>(&InnerBounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(InnerBounds->getStepInst().getName(), "inc");
+        StepValue = dyn_cast_or_null<ConstantInt>(InnerBounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(InnerBounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(InnerBounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(InnerBounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+      });
+}
+
+TEST(LoopInfoTest, AuxiliaryIV) {
+  const char *ModuleStr =
+      "define void @foo(i32* %A, i32 %ub) {\n"
+      "entry:\n"
+      "  %guardcmp = icmp slt i32 0, %ub\n"
+      "  br i1 %guardcmp, label %for.preheader, label %for.end\n"
+      "for.preheader:\n"
+      "  br label %for.body\n"
+      "for.body:\n"
+      "  %i = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]\n"
+      "  %aux = phi i32 [ 0, %for.preheader ], [ %auxinc, %for.body ]\n"
+      "  %loopvariant = phi i32 [ 0, %for.preheader ], [ %loopvariantinc, %for.body ]\n"
+      "  %usedoutside = phi i32 [ 0, %for.preheader ], [ %usedoutsideinc, %for.body ]\n"
+      "  %mulopcode = phi i32 [ 0, %for.preheader ], [ %mulopcodeinc, %for.body ]\n"
+      "  %idxprom = sext i32 %i to i64\n"
+      "  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom\n"
+      "  store i32 %i, i32* %arrayidx, align 4\n"
+      "  %mulopcodeinc = mul nsw i32 %mulopcode, 5\n"
+      "  %usedoutsideinc = add nsw i32 %usedoutside, 5\n"
+      "  %loopvariantinc = add nsw i32 %loopvariant, %i\n"
+      "  %auxinc = add nsw i32 %aux, 5\n"
+      "  %inc = add nsw i32 %i, 1\n"
+      "  %cmp = icmp slt i32 %inc, %ub\n"
+      "  br i1 %cmp, label %for.body, label %for.exit\n"
+      "for.exit:\n"
+      "  %lcssa = phi i32 [ %usedoutside, %for.body ]\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfoPlus(
+      *M, "foo",
+      [&](Function &F, LoopInfo &LI, ScalarEvolution &SE,
+          PostDominatorTree &PDT) {
+        Function::iterator FI = F.begin();
+        // First two basic block are entry and for.preheader - skip them.
+        ++FI;
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.body");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+
+        Optional<Loop::LoopBounds> Bounds = L->getBounds(SE);
+        EXPECT_NE(Bounds, None);
+        ConstantInt *InitialIVValue =
+            dyn_cast<ConstantInt>(&Bounds->getInitialIVValue());
+        EXPECT_TRUE(InitialIVValue && InitialIVValue->isZero());
+        EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
+        ConstantInt *StepValue =
+            dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
+        EXPECT_TRUE(StepValue && StepValue->isOne());
+        EXPECT_EQ(Bounds->getFinalIVValue().getName(), "ub");
+        EXPECT_EQ(Bounds->getCanonicalPredicate(), ICmpInst::ICMP_SLT);
+        EXPECT_EQ(Bounds->getDirection(),
+                  Loop::LoopBounds::Direction::Increasing);
+        EXPECT_EQ(L->getInductionVariable(SE)->getName(), "i");
+        BasicBlock::iterator II = Header->begin();
+        PHINode &Instruction_i = cast<PHINode>(*(II));
+        EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_i, SE));
+        PHINode &Instruction_aux = cast<PHINode>(*(++II));
+        EXPECT_TRUE(L->isAuxiliaryInductionVariable(Instruction_aux, SE));
+        PHINode &Instruction_loopvariant = cast<PHINode>(*(++II));
+        EXPECT_FALSE(
+            L->isAuxiliaryInductionVariable(Instruction_loopvariant, SE));
+        PHINode &Instruction_usedoutside = cast<PHINode>(*(++II));
+        EXPECT_FALSE(
+            L->isAuxiliaryInductionVariable(Instruction_usedoutside, SE));
+        PHINode &Instruction_mulopcode = cast<PHINode>(*(++II));
+        EXPECT_FALSE(
+            L->isAuxiliaryInductionVariable(Instruction_mulopcode, SE));
+      });
+}
+
+// Examine getUniqueExitBlocks/getUniqueNonLatchExitBlocks functions.
+TEST(LoopInfoTest, LoopUniqueExitBlocks) {
+  const char *ModuleStr =
+      "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
+      "define void @foo(i32 %n, i1 %cond) {\n"
+      "entry:\n"
+      "  br label %for.cond\n"
+      "for.cond:\n"
+      "  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]\n"
+      "  %cmp = icmp slt i32 %i.0, %n\n"
+      "  br i1 %cond, label %for.inc, label %for.end1\n"
+      "for.inc:\n"
+      "  %inc = add nsw i32 %i.0, 1\n"
+      "  br i1 %cmp, label %for.cond, label %for.end2, !llvm.loop !0\n"
+      "for.end1:\n"
+      "  br label %for.end\n"
+      "for.end2:\n"
+      "  br label %for.end\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n"
+      "!0 = distinct !{!0, !1}\n"
+      "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
+    Function::iterator FI = F.begin();
+    // First basic block is entry - skip it.
+    BasicBlock *Header = &*(++FI);
+    assert(Header->getName() == "for.cond");
+    Loop *L = LI.getLoopFor(Header);
+
+    SmallVector<BasicBlock *, 2> Exits;
+    // This loop has 2 unique exits.
+    L->getUniqueExitBlocks(Exits);
+    EXPECT_TRUE(Exits.size() == 2);
+    // And one unique non latch exit.
+    Exits.clear();
+    L->getUniqueNonLatchExitBlocks(Exits);
+    EXPECT_TRUE(Exits.size() == 1);
+  });
+}
+
+// Regression test for  getUniqueNonLatchExitBlocks functions.
+// It should detect the exit if it comes from both latch and non-latch blocks.
+TEST(LoopInfoTest, LoopNonLatchUniqueExitBlocks) {
+  const char *ModuleStr =
+      "target datalayout = \"e-m:o-i64:64-f80:128-n8:16:32:64-S128\"\n"
+      "define void @foo(i32 %n, i1 %cond) {\n"
+      "entry:\n"
+      "  br label %for.cond\n"
+      "for.cond:\n"
+      "  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]\n"
+      "  %cmp = icmp slt i32 %i.0, %n\n"
+      "  br i1 %cond, label %for.inc, label %for.end\n"
+      "for.inc:\n"
+      "  %inc = add nsw i32 %i.0, 1\n"
+      "  br i1 %cmp, label %for.cond, label %for.end, !llvm.loop !0\n"
+      "for.end:\n"
+      "  ret void\n"
+      "}\n"
+      "!0 = distinct !{!0, !1}\n"
+      "!1 = !{!\"llvm.loop.distribute.enable\", i1 true}\n";
+
+  // Parse the module.
+  LLVMContext Context;
+  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleStr);
+
+  runWithLoopInfo(*M, "foo", [&](Function &F, LoopInfo &LI) {
+    Function::iterator FI = F.begin();
+    // First basic block is entry - skip it.
+    BasicBlock *Header = &*(++FI);
+    assert(Header->getName() == "for.cond");
+    Loop *L = LI.getLoopFor(Header);
+
+    SmallVector<BasicBlock *, 2> Exits;
+    // This loop has 1 unique exit.
+    L->getUniqueExitBlocks(Exits);
+    EXPECT_TRUE(Exits.size() == 1);
+    // And one unique non latch exit.
+    Exits.clear();
+    L->getUniqueNonLatchExitBlocks(Exits);
+    EXPECT_TRUE(Exits.size() == 1);
+  });
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
index 898ebee..575b7f3 100644
--- a/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/MemoryBuiltinsTest.cpp
@@ -1,9 +1,8 @@
 //===- MemoryBuiltinsTest.cpp - Tests for utilities in MemoryBuiltins.h ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp b/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp
index 505e185..bfdf37e 100644
--- a/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/MemorySSATest.cpp
@@ -1,9 +1,8 @@
 //===- MemorySSA.cpp - Unit tests for MemorySSA ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/Analysis/MemorySSA.h"
@@ -93,7 +92,7 @@
   MemorySSAUpdater Updater(&MSSA);
   // Add the load
   B.SetInsertPoint(Merge);
-  LoadInst *LoadInst = B.CreateLoad(PointerArg);
+  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
 
   // MemoryPHI should already exist.
   MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
@@ -139,7 +138,7 @@
 
   // Add the load
   B.SetInsertPoint(Merge, Merge->begin());
-  LoadInst *FirstLoad = B.CreateLoad(PointerArg);
+  LoadInst *FirstLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
 
   // MemoryPHI should not already exist.
   MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
@@ -160,14 +159,14 @@
   MemoryAccess *LeftStoreAccess = Updater.createMemoryAccessInBB(
       LeftStore, nullptr, Left, MemorySSA::Beginning);
   Updater.insertDef(cast<MemoryDef>(LeftStoreAccess), false);
-  // We don't touch existing loads, so we need to create a new one to get a phi
+
+  // MemoryPHI should exist after adding LeftStore.
+  MP = MSSA.getMemoryAccess(Merge);
+  EXPECT_NE(MP, nullptr);
+
   // Add the second load
   B.SetInsertPoint(Merge, Merge->begin());
-  LoadInst *SecondLoad = B.CreateLoad(PointerArg);
-
-  // MemoryPHI should not already exist.
-  MP = MSSA.getMemoryAccess(Merge);
-  EXPECT_EQ(MP, nullptr);
+  LoadInst *SecondLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
 
   // Create the load memory access
   MemoryUse *SecondLoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
@@ -227,13 +226,13 @@
       Updater.createMemoryAccessInBB(SI, nullptr, Left, MemorySSA::Beginning);
   Updater.insertDef(cast<MemoryDef>(StoreAccess));
 
+  // MemoryPHI should be created when inserting the def
+  MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
+  EXPECT_NE(MP, nullptr);
+
   // Add the load
   B.SetInsertPoint(Merge, Merge->begin());
-  LoadInst *LoadInst = B.CreateLoad(PointerArg);
-
-  // MemoryPHI should not already exist.
-  MemoryPhi *MP = MSSA.getMemoryAccess(Merge);
-  EXPECT_EQ(MP, nullptr);
+  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
 
   // Create the load memory acccess
   MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
@@ -263,7 +262,7 @@
 
   // Load in left block
   B.SetInsertPoint(Left, Left->begin());
-  LoadInst *LoadInst1 = B.CreateLoad(PointerArg);
+  LoadInst *LoadInst1 = B.CreateLoad(B.getInt8Ty(), PointerArg);
   // Store in merge block
   B.SetInsertPoint(Merge, Merge->begin());
   B.CreateStore(B.getInt8(16), PointerArg);
@@ -311,7 +310,7 @@
   BranchInst::Create(Merge, Left);
   BranchInst::Create(Merge, Right);
   B.SetInsertPoint(Merge);
-  B.CreateLoad(PointerArg);
+  B.CreateLoad(B.getInt8Ty(), PointerArg);
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
   MemorySSAUpdater Updater(&MSSA);
@@ -347,7 +346,7 @@
   BranchInst::Create(Merge, Left);
   BranchInst::Create(Merge, Right);
   B.SetInsertPoint(Merge);
-  auto *MergeLoad = B.CreateLoad(PointerArg);
+  auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
   MemorySSAUpdater Updater(&MSSA);
@@ -393,7 +392,7 @@
   BranchInst::Create(Merge, Left);
   BranchInst::Create(Merge, Right);
   B.SetInsertPoint(Merge);
-  auto *MergeLoad = B.CreateLoad(PointerArg);
+  auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
   MemorySSAUpdater Updater(&MSSA);
@@ -437,7 +436,7 @@
   BranchInst::Create(Merge, Left);
   BranchInst::Create(Merge, Right);
   B.SetInsertPoint(Merge);
-  auto *MergeLoad = B.CreateLoad(PointerArg);
+  auto *MergeLoad = B.CreateLoad(B.getInt8Ty(), PointerArg);
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
   MemorySSAUpdater Updater(&MSSA);
@@ -491,7 +490,7 @@
   BranchInst::Create(Merge, Left);
   BranchInst::Create(Merge, Right);
   B.SetInsertPoint(Merge);
-  LoadInst *LoadInst = B.CreateLoad(PointerArg);
+  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -536,7 +535,7 @@
   BranchInst::Create(Merge, Left);
   BranchInst::Create(Merge, Right);
   B.SetInsertPoint(Merge);
-  LoadInst *LoadInst = B.CreateLoad(PointerArg);
+  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), PointerArg);
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -632,7 +631,7 @@
   Type *Int8 = Type::getInt8Ty(C);
   Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
   Instruction *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca);
-  Instruction *LI = B.CreateLoad(Alloca);
+  Instruction *LI = B.CreateLoad(Int8, Alloca);
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -716,12 +715,12 @@
   B.SetInsertPoint(IfThen);
   Instruction *FirstStore = B.CreateStore(Zero, AllocA);
   B.CreateStore(Zero, AllocB);
-  Instruction *ALoad0 = B.CreateLoad(AllocA, "");
+  Instruction *ALoad0 = B.CreateLoad(Int8, AllocA, "");
   Instruction *BStore = B.CreateStore(Zero, AllocB);
   // Due to use optimization/etc. we make a store to A, which is removed after
   // we build MSSA. This helps keep the test case simple-ish.
   Instruction *KillStore = B.CreateStore(Zero, AllocA);
-  Instruction *ALoad = B.CreateLoad(AllocA, "");
+  Instruction *ALoad = B.CreateLoad(Int8, AllocA, "");
   B.CreateBr(IfEnd);
 
   B.SetInsertPoint(IfEnd);
@@ -772,7 +771,7 @@
   Value *AllocA = B.CreateAlloca(Int8, One, "");
 
   Instruction *Store = B.CreateStore(One, AllocA);
-  Instruction *Load = B.CreateLoad(AllocA);
+  Instruction *Load = B.CreateLoad(Int8, AllocA);
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -801,7 +800,7 @@
   Instruction *SIA = B.CreateStore(ConstantInt::get(Int8, 0), AllocaA);
   Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
   Instruction *SIB = B.CreateStore(ConstantInt::get(Int8, 0), AllocaB);
-  Instruction *LIA = B.CreateLoad(AllocaA);
+  Instruction *LIA = B.CreateLoad(Int8, AllocaA);
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -835,11 +834,11 @@
 
   StoreInst *StoreA0 = B.CreateStore(ConstantInt::get(Int8, 0), A);
   StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 0), B_);
-  LoadInst *LoadB = B.CreateLoad(B_);
+  LoadInst *LoadB = B.CreateLoad(Int8, B_);
   StoreInst *StoreA1 = B.CreateStore(ConstantInt::get(Int8, 4), A);
   StoreInst *StoreC = B.CreateStore(ConstantInt::get(Int8, 4), C);
   StoreInst *StoreA2 = B.CreateStore(ConstantInt::get(Int8, 4), A);
-  LoadInst *LoadC = B.CreateLoad(C);
+  LoadInst *LoadC = B.CreateLoad(Int8, C);
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -903,7 +902,7 @@
   MemorySSA &MSSA = *Analyses->MSSA;
   MemorySSAUpdater Updater(&MSSA);
   // Create the load memory acccess
-  LoadInst *LoadInst = B.CreateLoad(FirstArg);
+  LoadInst *LoadInst = B.CreateLoad(B.getInt8Ty(), FirstArg);
   MemoryUse *LoadAccess = cast<MemoryUse>(Updater.createMemoryAccessInBB(
       LoadInst, nullptr, AfterLoopBB, MemorySSA::Beginning));
   Updater.insertUse(LoadAccess);
@@ -1011,15 +1010,15 @@
 
   B.CreateStore(ConstantInt::get(Int8, 1), AllocaB);
   // Check load from LOE
-  LoadInst *LA1 = B.CreateLoad(AllocaA, "");
+  LoadInst *LA1 = B.CreateLoad(Int8, AllocaA, "");
   // Check load alias cached for second load
-  LoadInst *LA2 = B.CreateLoad(AllocaA, "");
+  LoadInst *LA2 = B.CreateLoad(Int8, AllocaA, "");
 
   B.CreateStore(ConstantInt::get(Int8, 1), AllocaA);
   // Check load from store/def
-  LoadInst *LA3 = B.CreateLoad(AllocaA, "");
+  LoadInst *LA3 = B.CreateLoad(Int8, AllocaA, "");
   // Check load alias cached for second load
-  LoadInst *LA4 = B.CreateLoad(AllocaA, "");
+  LoadInst *LA4 = B.CreateLoad(Int8, AllocaA, "");
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -1104,13 +1103,13 @@
   Argument *PointerA = &*ArgIt;
   Argument *PointerB = &*(++ArgIt);
   B.CreateStore(ConstantInt::get(Int8, 1), PointerB);
-  LoadInst *LA1 = B.CreateLoad(PointerA, "");
+  LoadInst *LA1 = B.CreateLoad(Int8, PointerA, "");
   B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
-  LoadInst *LB1 = B.CreateLoad(PointerB, "");
+  LoadInst *LB1 = B.CreateLoad(Int8, PointerB, "");
   B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
-  LoadInst *LA2 = B.CreateLoad(PointerA, "");
+  LoadInst *LA2 = B.CreateLoad(Int8, PointerA, "");
   B.CreateStore(ConstantInt::get(Int8, 0), PointerB);
-  LoadInst *LB2 = B.CreateLoad(PointerB, "");
+  LoadInst *LB2 = B.CreateLoad(Int8, PointerB, "");
 
   setupAnalyses();
   MemorySSA &MSSA = *Analyses->MSSA;
@@ -1228,7 +1227,7 @@
   B.SetInsertPoint(Entry);
   Value *Foo = &*F->arg_begin();
 
-  Value *Bar = B.CreateGEP(Foo, B.getInt64(1), "bar");
+  Value *Bar = B.CreateGEP(B.getInt8Ty(), Foo, B.getInt64(1), "bar");
 
   B.CreateStore(B.getInt8(0), Foo);
   B.CreateStore(B.getInt8(0), Bar);
diff --git a/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp b/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp
index b8b9ff0..4cccb38 100644
--- a/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/OrderedBasicBlockTest.cpp
@@ -1,9 +1,8 @@
 //===- OrderedBasicBlockTest.cpp - OrderedBasicBlock unit tests -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp
index dc1b25b..473fe7f 100644
--- a/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/OrderedInstructionsTest.cpp
@@ -1,9 +1,8 @@
 //===- OrderedInstructions.cpp - Unit tests for OrderedInstructions  ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -26,7 +25,7 @@
   IRBuilder<> B(Ctx);
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
 
   // Create the function as follow and check for dominance relation.
   //
@@ -45,13 +44,13 @@
   BasicBlock *BBX = BasicBlock::Create(Ctx, "bbx", F);
   B.SetInsertPoint(BBX);
   Argument *PointerArg = &*F->arg_begin();
-  LoadInst *LoadInstX = B.CreateLoad(PointerArg);
-  LoadInst *LoadInstY = B.CreateLoad(PointerArg);
+  LoadInst *LoadInstX = B.CreateLoad(B.getInt8Ty(), PointerArg);
+  LoadInst *LoadInstY = B.CreateLoad(B.getInt8Ty(), PointerArg);
 
   // Create BBY with 1 load.
   BasicBlock *BBY = BasicBlock::Create(Ctx, "bby", F);
   B.SetInsertPoint(BBY);
-  LoadInst *LoadInstZ = B.CreateLoad(PointerArg);
+  LoadInst *LoadInstZ = B.CreateLoad(B.getInt8Ty(), PointerArg);
   B.CreateRet(LoadInstZ);
   std::unique_ptr<DominatorTree> DT(new DominatorTree(*F));
   OrderedInstructions OI(&*DT);
diff --git a/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp b/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp
index 303b0df..82c0233 100644
--- a/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/PhiValuesTest.cpp
@@ -1,9 +1,8 @@
 //===- PhiValuesTest.cpp - PhiValues unit tests ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,7 +26,8 @@
   Type *I32PtrTy = Type::getInt32PtrTy(C);
 
   // Create a function with phis that do not have other phis as incoming values
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FunctionType::get(VoidTy, false)));
+  Function *F = Function::Create(FunctionType::get(VoidTy, false),
+                                 Function::ExternalLinkage, "f", M);
 
   BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
   BasicBlock *If = BasicBlock::Create(C, "if", F);
@@ -37,10 +37,10 @@
   BranchInst::Create(Then, If);
   BranchInst::Create(Then, Else);
 
-  Value *Val1 = new LoadInst(UndefValue::get(I32PtrTy), "val1", Entry);
-  Value *Val2 = new LoadInst(UndefValue::get(I32PtrTy), "val2", Entry);
-  Value *Val3 = new LoadInst(UndefValue::get(I32PtrTy), "val3", Entry);
-  Value *Val4 = new LoadInst(UndefValue::get(I32PtrTy), "val4", Entry);
+  Value *Val1 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val1", Entry);
+  Value *Val2 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val2", Entry);
+  Value *Val3 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val3", Entry);
+  Value *Val4 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val4", Entry);
 
   PHINode *Phi1 = PHINode::Create(I32Ty, 2, "phi1", Then);
   Phi1->addIncoming(Val1, If);
@@ -93,7 +93,8 @@
   Type *I32PtrTy = Type::getInt32PtrTy(C);
 
   // Create a function with a phi that has another phi as an incoming value
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FunctionType::get(VoidTy, false)));
+  Function *F = Function::Create(FunctionType::get(VoidTy, false),
+                                 Function::ExternalLinkage, "f", M);
 
   BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
   BasicBlock *If1 = BasicBlock::Create(C, "if1", F);
@@ -109,10 +110,10 @@
   BranchInst::Create(End, If2);
   BranchInst::Create(End, Else2);
 
-  Value *Val1 = new LoadInst(UndefValue::get(I32PtrTy), "val1", Entry);
-  Value *Val2 = new LoadInst(UndefValue::get(I32PtrTy), "val2", Entry);
-  Value *Val3 = new LoadInst(UndefValue::get(I32PtrTy), "val3", Entry);
-  Value *Val4 = new LoadInst(UndefValue::get(I32PtrTy), "val4", Entry);
+  Value *Val1 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val1", Entry);
+  Value *Val2 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val2", Entry);
+  Value *Val3 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val3", Entry);
+  Value *Val4 = new LoadInst(I32Ty, UndefValue::get(I32PtrTy), "val4", Entry);
 
   PHINode *Phi1 = PHINode::Create(I32Ty, 2, "phi1", Then);
   Phi1->addIncoming(Val1, If1);
diff --git a/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
index 95d8426..002901d 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
@@ -1,9 +1,8 @@
 //===- ProfileSummaryInfoTest.cpp - ProfileSummaryInfo unit tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
index 3da0614bb..fb8f668 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -1,9 +1,8 @@
 //===- ScalarEvolutionsTest.cpp - ScalarEvolution unit tests --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -64,7 +63,7 @@
 TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) {
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
                                               std::vector<Type *>(), false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
   ReturnInst::Create(Context, nullptr, BB);
 
@@ -113,7 +112,7 @@
 TEST_F(ScalarEvolutionsTest, SimplifiedPHI) {
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
                                               std::vector<Type *>(), false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
   BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
   BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
@@ -147,7 +146,7 @@
   auto *I32PtrTy = Type::getInt32PtrTy(Context);
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
   BasicBlock *LoopBB = BasicBlock::Create(Context, "loop", F);
   BasicBlock *ExitBB = BasicBlock::Create(Context, "exit", F);
@@ -330,7 +329,7 @@
 TEST_F(ScalarEvolutionsTest, CompareSCEVComplexity) {
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
   BasicBlock *LoopBB = BasicBlock::Create(Context, "bb1", F);
   BranchInst::Create(LoopBB, EntryBB);
@@ -400,7 +399,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), {IntPtrTy, IntPtrTy}, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
 
   Value *X = &*F->arg_begin();
@@ -408,9 +407,11 @@
 
   const int ValueDepth = 10;
   for (int i = 0; i < ValueDepth; i++) {
-    X = new LoadInst(new IntToPtrInst(X, IntPtrPtrTy, "", EntryBB), "",
+    X = new LoadInst(IntPtrTy, new IntToPtrInst(X, IntPtrPtrTy, "", EntryBB),
+                     "",
                      /*isVolatile*/ false, EntryBB);
-    Y = new LoadInst(new IntToPtrInst(Y, IntPtrPtrTy, "", EntryBB), "",
+    Y = new LoadInst(IntPtrTy, new IntToPtrInst(Y, IntPtrPtrTy, "", EntryBB),
+                     "",
                      /*isVolatile*/ false, EntryBB);
   }
 
@@ -436,7 +437,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), ArgTys, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
 
   Argument *A1 = &*F->arg_begin();
   Argument *A2 = &*(std::next(F->arg_begin()));
@@ -670,7 +671,7 @@
   //   ret void
   // }
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), {}, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
 
   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", F);
   BasicBlock *CondBB = BasicBlock::Create(Context, "for.cond", F);
@@ -749,7 +750,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
-  Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
 
   Argument *Arg = &*F->arg_begin();
 
@@ -772,7 +773,8 @@
   Phi->addIncoming(Add, L);
 
   Builder.SetInsertPoint(Post);
-  Value *GepBase = Builder.CreateGEP(Arg, ConstantInt::get(T_int64, 1));
+  Value *GepBase =
+      Builder.CreateGEP(T_int64, Arg, ConstantInt::get(T_int64, 1));
   Instruction *Ret = Builder.CreateRetVoid();
 
   ScalarEvolution SE = buildSE(*F);
@@ -822,7 +824,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
-  Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
 
   BasicBlock *Top = BasicBlock::Create(Context, "top", F);
   BasicBlock *LPh = BasicBlock::Create(Context, "L.ph", F);
@@ -920,7 +922,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
-  Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
 
   Argument *Arg = &*F->arg_begin();
 
@@ -980,7 +982,8 @@
   // ix.
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), std::vector<Type *>(), false);
-  Function *F = cast<Function>(M.getOrInsertFunction("addrecphitest", FTy));
+  Function *F =
+      Function::Create(FTy, Function::ExternalLinkage, "addrecphitest", M);
 
   /*
     Create IR:
@@ -1036,7 +1039,8 @@
   SmallVector<Type *, 1> Types;
   Types.push_back(Int32Ty);
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("addrecphitest", FTy));
+  Function *F =
+      Function::Create(FTy, Function::ExternalLinkage, "addrecphitest", M);
 
   /*
     Create IR:
@@ -1090,7 +1094,7 @@
   SmallVector<Type *, 1> Types;
   Types.push_back(ArgTy);
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
   BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
   ReturnInst::Create(Context, nullptr, BB);
 
@@ -1146,7 +1150,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), {T_pint64}, false);
-  Function *F = cast<Function>(NIM.getOrInsertFunction("foo", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", NIM);
 
   BasicBlock *Top = BasicBlock::Create(Context, "top", F);
   BasicBlock *LPh = BasicBlock::Create(Context, "L.ph", F);
@@ -1207,7 +1211,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
   Argument *Arg = &*F->arg_begin();
   ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
 
@@ -1259,7 +1263,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
   Argument *Arg = &*F->arg_begin();
   ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
 
@@ -1309,7 +1313,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
   Argument *Arg = &*F->arg_begin();
   ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
 
@@ -1360,7 +1364,7 @@
 
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(Context), { T_int64 }, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("func", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
   Argument *Arg = &*F->arg_begin();
   ConstantInt *C = ConstantInt::get(Context, APInt(64, -1));
 
@@ -1390,5 +1394,289 @@
   EXPECT_FALSE(I->hasNoSignedWrap());
 }
 
+// Check logic of SCEV expression size computation.
+TEST_F(ScalarEvolutionsTest, SCEVComputeExpressionSize) {
+  /*
+   * Create the following code:
+   * void func(i64 %a, i64 %b)
+   * entry:
+   *  %s1 = add i64 %a, 1
+   *  %s2 = udiv i64 %s1, %b
+   *  br label %exit
+   * exit:
+   *  ret
+   */
+
+  // Create a module.
+  Module M("SCEVComputeExpressionSize", Context);
+
+  Type *T_int64 = Type::getInt64Ty(Context);
+
+  FunctionType *FTy =
+      FunctionType::get(Type::getVoidTy(Context), { T_int64, T_int64 }, false);
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "func", M);
+  Argument *A = &*F->arg_begin();
+  Argument *B = &*std::next(F->arg_begin());
+  ConstantInt *C = ConstantInt::get(Context, APInt(64, 1));
+
+  BasicBlock *Entry = BasicBlock::Create(Context, "entry", F);
+  BasicBlock *Exit = BasicBlock::Create(Context, "exit", F);
+
+  IRBuilder<> Builder(Entry);
+  auto *S1 = cast<Instruction>(Builder.CreateAdd(A, C, "s1"));
+  auto *S2 = cast<Instruction>(Builder.CreateUDiv(S1, B, "s2"));
+  Builder.CreateBr(Exit);
+
+  Builder.SetInsertPoint(Exit);
+  Builder.CreateRetVoid();
+
+  ScalarEvolution SE = buildSE(*F);
+  // Get S2 first to move it to cache.
+  const SCEV *AS = SE.getSCEV(A);
+  const SCEV *BS = SE.getSCEV(B);
+  const SCEV *CS = SE.getSCEV(C);
+  const SCEV *S1S = SE.getSCEV(S1);
+  const SCEV *S2S = SE.getSCEV(S2);
+  EXPECT_EQ(AS->getExpressionSize(), 1u);
+  EXPECT_EQ(BS->getExpressionSize(), 1u);
+  EXPECT_EQ(CS->getExpressionSize(), 1u);
+  EXPECT_EQ(S1S->getExpressionSize(), 3u);
+  EXPECT_EQ(S2S->getExpressionSize(), 5u);
+}
+
+TEST_F(ScalarEvolutionsTest, SCEVExpandInsertCanonicalIV) {
+  LLVMContext C;
+  SMDiagnostic Err;
+
+  // Expand the addrec produced by GetAddRec into a loop without a canonical IV.
+  // SCEVExpander will insert one.
+  auto TestNoCanonicalIV = [&](
+      std::function<const SCEV *(ScalarEvolution & SE, Loop * L)> GetAddRec) {
+    std::unique_ptr<Module> M =
+        parseAssemblyString("define i32 @test(i32 %limit) { "
+                            "entry: "
+                            "  br label %loop "
+                            "loop: "
+                            "  %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
+                            "  %i.inc = add nsw i32 %i, 1 "
+                            "  %cont = icmp slt i32 %i.inc, %limit "
+                            "  br i1 %cont, label %loop, label %exit "
+                            "exit: "
+                            "  ret i32 %i.inc "
+                            "}",
+                            Err, C);
+
+    assert(M && "Could not parse module?");
+    assert(!verifyModule(*M) && "Must have been well formed!");
+
+    runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+      auto &I = GetInstByName(F, "i");
+      auto *Loop = LI.getLoopFor(I.getParent());
+      EXPECT_FALSE(Loop->getCanonicalInductionVariable());
+
+      auto *AR = GetAddRec(SE, Loop);
+      unsigned ExpectedCanonicalIVWidth = SE.getTypeSizeInBits(AR->getType());
+
+      SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+      auto *InsertAt = I.getNextNode();
+      Exp.expandCodeFor(AR, nullptr, InsertAt);
+      PHINode *CanonicalIV = Loop->getCanonicalInductionVariable();
+      unsigned CanonicalIVBitWidth =
+          cast<IntegerType>(CanonicalIV->getType())->getBitWidth();
+      EXPECT_EQ(CanonicalIVBitWidth, ExpectedCanonicalIVWidth);
+    });
+  };
+
+  // Expand the addrec produced by GetAddRec into a loop with a canonical IV
+  // which is narrower than addrec type.
+  // SCEVExpander will insert a canonical IV of a wider type to expand the
+  // addrec.
+  auto TestNarrowCanonicalIV = [&](
+      std::function<const SCEV *(ScalarEvolution & SE, Loop * L)> GetAddRec) {
+    std::unique_ptr<Module> M = parseAssemblyString(
+        "define i32 @test(i32 %limit) { "
+        "entry: "
+        "  br label %loop "
+        "loop: "
+        "  %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
+        "  %canonical.iv = phi i8 [ 0, %entry ], [ %canonical.iv.inc, %loop ] "
+        "  %i.inc = add nsw i32 %i, 1 "
+        "  %canonical.iv.inc = add i8 %canonical.iv, 1 "
+        "  %cont = icmp slt i32 %i.inc, %limit "
+        "  br i1 %cont, label %loop, label %exit "
+        "exit: "
+        "  ret i32 %i.inc "
+        "}",
+        Err, C);
+
+    assert(M && "Could not parse module?");
+    assert(!verifyModule(*M) && "Must have been well formed!");
+
+    runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+      auto &I = GetInstByName(F, "i");
+
+      auto *LoopHeaderBB = I.getParent();
+      auto *Loop = LI.getLoopFor(LoopHeaderBB);
+      PHINode *CanonicalIV = Loop->getCanonicalInductionVariable();
+      EXPECT_EQ(CanonicalIV, &GetInstByName(F, "canonical.iv"));
+
+      auto *AR = GetAddRec(SE, Loop);
+
+      unsigned ExpectedCanonicalIVWidth = SE.getTypeSizeInBits(AR->getType());
+      unsigned CanonicalIVBitWidth =
+          cast<IntegerType>(CanonicalIV->getType())->getBitWidth();
+      EXPECT_LT(CanonicalIVBitWidth, ExpectedCanonicalIVWidth);
+
+      SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+      auto *InsertAt = I.getNextNode();
+      Exp.expandCodeFor(AR, nullptr, InsertAt);
+
+      // Loop over all of the PHI nodes, looking for the new canonical indvar.
+      PHINode *NewCanonicalIV = nullptr;
+      for (BasicBlock::iterator i = LoopHeaderBB->begin(); isa<PHINode>(i);
+           ++i) {
+        PHINode *PN = cast<PHINode>(i);
+        if (PN == &I || PN == CanonicalIV)
+          continue;
+        // We expect that the only PHI added is the new canonical IV
+        EXPECT_FALSE(NewCanonicalIV);
+        NewCanonicalIV = PN;
+      }
+
+      // Check that NewCanonicalIV is a canonical IV, i.e {0,+,1}
+      BasicBlock *Incoming = nullptr, *Backedge = nullptr;
+      EXPECT_TRUE(Loop->getIncomingAndBackEdge(Incoming, Backedge));
+      auto *Start = NewCanonicalIV->getIncomingValueForBlock(Incoming);
+      EXPECT_TRUE(isa<ConstantInt>(Start));
+      EXPECT_TRUE(dyn_cast<ConstantInt>(Start)->isZero());
+      auto *Next = NewCanonicalIV->getIncomingValueForBlock(Backedge);
+      EXPECT_TRUE(isa<BinaryOperator>(Next));
+      auto *NextBinOp = dyn_cast<BinaryOperator>(Next);
+      EXPECT_EQ(NextBinOp->getOpcode(), Instruction::Add);
+      EXPECT_EQ(NextBinOp->getOperand(0), NewCanonicalIV);
+      auto *Step = NextBinOp->getOperand(1);
+      EXPECT_TRUE(isa<ConstantInt>(Step));
+      EXPECT_TRUE(dyn_cast<ConstantInt>(Step)->isOne());
+
+      unsigned NewCanonicalIVBitWidth =
+          cast<IntegerType>(NewCanonicalIV->getType())->getBitWidth();
+      EXPECT_EQ(NewCanonicalIVBitWidth, ExpectedCanonicalIVWidth);
+    });
+  };
+
+  // Expand the addrec produced by GetAddRec into a loop with a canonical IV
+  // of addrec width.
+  // To expand the addrec SCEVExpander should use the existing canonical IV.
+  auto TestMatchingCanonicalIV = [&](
+      std::function<const SCEV *(ScalarEvolution & SE, Loop * L)> GetAddRec,
+      unsigned ARBitWidth) {
+    auto ARBitWidthTypeStr = "i" + std::to_string(ARBitWidth);
+    std::unique_ptr<Module> M = parseAssemblyString(
+        "define i32 @test(i32 %limit) { "
+        "entry: "
+        "  br label %loop "
+        "loop: "
+        "  %i = phi i32 [ 1, %entry ], [ %i.inc, %loop ] "
+        "  %canonical.iv = phi " + ARBitWidthTypeStr +
+            " [ 0, %entry ], [ %canonical.iv.inc, %loop ] "
+        "  %i.inc = add nsw i32 %i, 1 "
+        "  %canonical.iv.inc = add " + ARBitWidthTypeStr +
+            " %canonical.iv, 1 "
+        "  %cont = icmp slt i32 %i.inc, %limit "
+        "  br i1 %cont, label %loop, label %exit "
+        "exit: "
+        "  ret i32 %i.inc "
+        "}",
+        Err, C);
+
+    assert(M && "Could not parse module?");
+    assert(!verifyModule(*M) && "Must have been well formed!");
+
+    runWithSE(*M, "test", [&](Function &F, LoopInfo &LI, ScalarEvolution &SE) {
+      auto &I = GetInstByName(F, "i");
+      auto &CanonicalIV = GetInstByName(F, "canonical.iv");
+
+      auto *LoopHeaderBB = I.getParent();
+      auto *Loop = LI.getLoopFor(LoopHeaderBB);
+      EXPECT_EQ(&CanonicalIV, Loop->getCanonicalInductionVariable());
+      unsigned CanonicalIVBitWidth =
+          cast<IntegerType>(CanonicalIV.getType())->getBitWidth();
+
+      auto *AR = GetAddRec(SE, Loop);
+      EXPECT_EQ(ARBitWidth, SE.getTypeSizeInBits(AR->getType()));
+      EXPECT_EQ(CanonicalIVBitWidth, ARBitWidth);
+
+      SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+      auto *InsertAt = I.getNextNode();
+      Exp.expandCodeFor(AR, nullptr, InsertAt);
+
+      // Loop over all of the PHI nodes, looking if a new canonical indvar was
+      // introduced.
+      PHINode *NewCanonicalIV = nullptr;
+      for (BasicBlock::iterator i = LoopHeaderBB->begin(); isa<PHINode>(i);
+           ++i) {
+        PHINode *PN = cast<PHINode>(i);
+        if (PN == &I || PN == &CanonicalIV)
+          continue;
+        NewCanonicalIV = PN;
+      }
+      EXPECT_FALSE(NewCanonicalIV);
+    });
+  };
+
+  unsigned ARBitWidth = 16;
+  Type *ARType = IntegerType::get(C, ARBitWidth);
+
+  // Expand {5,+,1}
+  auto GetAR2 = [&](ScalarEvolution &SE, Loop *L) -> const SCEV * {
+    return SE.getAddRecExpr(SE.getConstant(APInt(ARBitWidth, 5)),
+                            SE.getOne(ARType), L, SCEV::FlagAnyWrap);
+  };
+  TestNoCanonicalIV(GetAR2);
+  TestNarrowCanonicalIV(GetAR2);
+  TestMatchingCanonicalIV(GetAR2, ARBitWidth);
+}
+
+TEST_F(ScalarEvolutionsTest, SCEVExpanderShlNSW) {
+
+  auto checkOneCase = [this](std::string &&str) {
+    LLVMContext C;
+    SMDiagnostic Err;
+    std::unique_ptr<Module> M = parseAssemblyString(str, Err, C);
+
+    assert(M && "Could not parse module?");
+    assert(!verifyModule(*M) && "Must have been well formed!");
+
+    Function *F = M->getFunction("f");
+    ASSERT_NE(F, nullptr) << "Could not find function 'f'";
+
+    BasicBlock &Entry = F->getEntryBlock();
+    LoadInst *Load = cast<LoadInst>(&Entry.front());
+    BinaryOperator *And = cast<BinaryOperator>(*Load->user_begin());
+
+    ScalarEvolution SE = buildSE(*F);
+    const SCEV *AndSCEV = SE.getSCEV(And);
+    EXPECT_TRUE(isa<SCEVMulExpr>(AndSCEV));
+    EXPECT_TRUE(cast<SCEVMulExpr>(AndSCEV)->hasNoSignedWrap());
+
+    SCEVExpander Exp(SE, M->getDataLayout(), "expander");
+    auto *I = cast<Instruction>(Exp.expandCodeFor(AndSCEV, nullptr, And));
+    EXPECT_EQ(I->getOpcode(), Instruction::Shl);
+    EXPECT_FALSE(I->hasNoSignedWrap());
+  };
+
+  checkOneCase("define void @f(i16* %arrayidx) { "
+               "  %1 = load i16, i16* %arrayidx "
+               "  %2 = and i16 %1, -32768 "
+               "  ret void "
+               "} ");
+
+  checkOneCase("define void @f(i8* %arrayidx) { "
+               "  %1 = load i8, i8* %arrayidx "
+               "  %2 = and i8 %1, -128 "
+               "  ret void "
+               "} ");
+}
+
 }  // end anonymous namespace
 }  // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp b/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp
index 298b140..bab14a2 100644
--- a/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/SparsePropagation.cpp
@@ -1,9 +1,8 @@
 //===- SparsePropagation.cpp - Unit tests for the generic solver ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -382,7 +381,7 @@
   BasicBlock *Else = BasicBlock::Create(Context, "else", F);
   F->arg_begin()->setName("cond");
   Builder.SetInsertPoint(If);
-  LoadInst *Cond = Builder.CreateLoad(F->arg_begin());
+  LoadInst *Cond = Builder.CreateLoad(Type::getInt1Ty(Context), F->arg_begin());
   Builder.CreateCondBr(Cond, Then, Else);
   Builder.SetInsertPoint(Then);
   Builder.CreateRet(Builder.getInt64(1));
@@ -422,7 +421,7 @@
   BasicBlock *Else = BasicBlock::Create(Context, "else", F);
   F->arg_begin()->setName("cond");
   Builder.SetInsertPoint(If);
-  LoadInst *Cond = Builder.CreateLoad(F->arg_begin());
+  LoadInst *Cond = Builder.CreateLoad(Type::getInt1Ty(Context), F->arg_begin());
   Builder.CreateCondBr(Cond, Then, Else);
   Builder.SetInsertPoint(Then);
   Builder.CreateRet(Builder.getInt64(0));
diff --git a/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp b/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp
index f3f05d8..5a71c74 100644
--- a/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/TBAATest.cpp
@@ -1,9 +1,8 @@
 //===--- TBAATest.cpp - Mixed TBAA unit tests -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -34,7 +33,7 @@
 static StoreInst *getFunctionWithSingleStore(Module *M, StringRef Name) {
   auto &C = M->getContext();
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {});
-  auto *F = cast<Function>(M->getOrInsertFunction(Name, FTy));
+  auto *F = Function::Create(FTy, Function::ExternalLinkage, Name, M);
   auto *BB = BasicBlock::Create(C, "entry", F);
   auto *IntType = Type::getInt32Ty(C);
   auto *PtrType = Type::getInt32PtrTy(C);
diff --git a/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index 482d9d8..00b1e94 100644
--- a/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -1,9 +1,8 @@
 //===--- TargetLibraryInfoTest.cpp - TLI/LibFunc unit tests ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -68,7 +67,7 @@
   for (unsigned FI = 0; FI != LibFunc::NumLibFuncs; ++FI) {
     LibFunc LF = (LibFunc)FI;
     auto *F = cast<Function>(
-        M->getOrInsertFunction(TLI.getName(LF), InvalidFTy));
+        M->getOrInsertFunction(TLI.getName(LF), InvalidFTy).getCallee());
     EXPECT_FALSE(isLibFunc(F, LF));
   }
 }
@@ -314,6 +313,8 @@
       "declare i8* @strtok(i8*, i8*)\n"
       "declare i8* @strtok_r(i8*, i8*, i8**)\n"
       "declare i64 @strtol(i8*, i8**, i32)\n"
+      "declare i64 @strlcat(i8*, i8**, i64)\n"
+      "declare i64 @strlcpy(i8*, i8**, i64)\n"
       "declare x86_fp80 @strtold(i8*, i8**)\n"
       "declare i64 @strtoll(i8*, i8**, i32)\n"
       "declare i64 @strtoul(i8*, i8**, i32)\n"
@@ -468,6 +469,15 @@
       "declare i8* @__stpncpy_chk(i8*, i8*, i64, i64)\n"
       "declare i8* @__strcpy_chk(i8*, i8*, i64)\n"
       "declare i8* @__strncpy_chk(i8*, i8*, i64, i64)\n"
+      "declare i8* @__memccpy_chk(i8*, i8*, i32, i64)\n"
+      "declare i32 @__snprintf_chk(i8*, i64, i32, i64, i8*, ...)\n"
+      "declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...)\n"
+      "declare i8* @__strcat_chk(i8*, i8*, i64)\n"
+      "declare i64 @__strlcat_chk(i8*, i8*, i64, i64)\n"
+      "declare i8* @__strncat_chk(i8*, i8*, i64, i64)\n"
+      "declare i64 @__strlcpy_chk(i8*, i8*, i64, i64)\n"
+      "declare i32 @__vsnprintf_chk(i8*, i64, i32, i64, i8*, %struct*)\n"
+      "declare i32 @__vsprintf_chk(i8*, i32, i64, i8*, %struct*)\n"
 
       "declare i8* @memalign(i64, i64)\n"
       "declare i8* @mempcpy(i8*, i8*, i64)\n"
@@ -495,6 +505,11 @@
       "declare i32 @iprintf(i8*, ...)\n"
       "declare i32 @siprintf(i8*, i8*, ...)\n"
 
+      // __small_printf variants have the same prototype as the non-'i' versions.
+      "declare i32 @__small_fprintf(%struct*, i8*, ...)\n"
+      "declare i32 @__small_printf(i8*, ...)\n"
+      "declare i32 @__small_sprintf(i8*, i8*, ...)\n"
+
       "declare i32 @htonl(i32)\n"
       "declare i16 @htons(i16)\n"
       "declare i32 @ntohl(i32)\n"
diff --git a/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp b/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp
index 937e69f..dfa4267 100644
--- a/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/UnrollAnalyzerTest.cpp
@@ -1,9 +1,8 @@
 //===- UnrollAnalyzerTest.cpp - UnrollAnalyzer unit tests -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp
index b0b3797..844254e 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ValueLatticeTest.cpp
@@ -1,9 +1,8 @@
 //===- ValueLatticeTest.cpp - ScalarEvolution unit tests --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp b/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 5b36d63..96b41d9 100644
--- a/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/src/llvm-project/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1,9 +1,8 @@
 //===- ValueTrackingTest.cpp - ValueTracking tests ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,8 +13,8 @@
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/KnownBits.h"
+#include "llvm/Support/SourceMgr.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -24,21 +23,26 @@
 
 class ValueTrackingTest : public testing::Test {
 protected:
-  void parseAssembly(const char *Assembly) {
+  std::unique_ptr<Module> parseModule(StringRef Assembly) {
     SMDiagnostic Error;
-    M = parseAssemblyString(Assembly, Error, Context);
+    std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
 
     std::string errMsg;
     raw_string_ostream os(errMsg);
     Error.print("", os);
+    EXPECT_TRUE(M) << os.str();
 
-    // A failure here means that the test itself is buggy.
-    if (!M)
-      report_fatal_error(os.str());
+    return M;
+  }
+
+  void parseAssembly(StringRef Assembly) {
+    M = parseModule(Assembly);
+    ASSERT_TRUE(M);
 
     Function *F = M->getFunction("test");
-    if (F == nullptr)
-      report_fatal_error("Test must have a function named @test");
+    ASSERT_TRUE(F) << "Test must have a function @test";
+    if (!F)
+      return;
 
     A = nullptr;
     for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
@@ -47,13 +51,12 @@
           A = &*I;
       }
     }
-    if (A == nullptr)
-      report_fatal_error("@test must have an instruction %A");
+    ASSERT_TRUE(A) << "@test must have an instruction %A";
   }
 
   LLVMContext Context;
   std::unique_ptr<Module> M;
-  Instruction *A;
+  Instruction *A = nullptr;
 };
 
 class MatchSelectPatternTest : public ValueTrackingTest {
@@ -465,6 +468,7 @@
       "declare void @nounwind_argmemonly(i32*) nounwind argmemonly "
       "declare void @throws_but_readonly(i32*) readonly "
       "declare void @throws_but_argmemonly(i32*) argmemonly "
+      "declare void @nounwind_willreturn(i32*) nounwind willreturn"
       " "
       "declare void @unknown(i32*) "
       " "
@@ -477,6 +481,7 @@
       "  call void @unknown(i32* %p) nounwind argmemonly "
       "  call void @unknown(i32* %p) readonly "
       "  call void @unknown(i32* %p) argmemonly "
+      "  call void @nounwind_willreturn(i32* %p)"
       "  ret void "
       "} ";
 
@@ -498,6 +503,7 @@
       true,  // call void @unknown(i32* %p) nounwind argmemonly
       false, // call void @unknown(i32* %p) readonly
       false, // call void @unknown(i32* %p) argmemonly
+      true,  // call void @nounwind_willreturn(i32* %p)
       false, // ret void
   };
 
@@ -616,3 +622,327 @@
       "declare i16 @llvm.fshl.i16(i16, i16, i16)\n");
   expectKnownBits(/*zero*/ 15u, /*one*/ 3840u);
 }
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatLeadingOnes) {
+  // uadd.sat(1111...1, ........)
+  // = 1111....
+  parseAssembly(
+      "define i8 @test(i8 %a, i8 %b) {\n"
+      "  %aa = or i8 %a, 241\n"
+      "  %A = call i8 @llvm.uadd.sat.i8(i8 %aa, i8 %b)\n"
+      "  ret i8 %A\n"
+      "}\n"
+      "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");
+  expectKnownBits(/*zero*/ 0u, /*one*/ 240u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUAddSatOnesPreserved) {
+  // uadd.sat(00...011, .1...110)
+  // = .......1
+  parseAssembly(
+      "define i8 @test(i8 %a, i8 %b) {\n"
+      "  %aa = or i8 %a, 3\n"
+      "  %aaa = and i8 %aa, 59\n"
+      "  %bb = or i8 %b, 70\n"
+      "  %bbb = and i8 %bb, 254\n"
+      "  %A = call i8 @llvm.uadd.sat.i8(i8 %aaa, i8 %bbb)\n"
+      "  ret i8 %A\n"
+      "}\n"
+      "declare i8 @llvm.uadd.sat.i8(i8, i8)\n");
+  expectKnownBits(/*zero*/ 0u, /*one*/ 1u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatLHSLeadingZeros) {
+  // usub.sat(0000...0, ........)
+  // = 0000....
+  parseAssembly(
+      "define i8 @test(i8 %a, i8 %b) {\n"
+      "  %aa = and i8 %a, 14\n"
+      "  %A = call i8 @llvm.usub.sat.i8(i8 %aa, i8 %b)\n"
+      "  ret i8 %A\n"
+      "}\n"
+      "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
+  expectKnownBits(/*zero*/ 240u, /*one*/ 0u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatRHSLeadingOnes) {
+  // usub.sat(........, 1111...1)
+  // = 0000....
+  parseAssembly(
+      "define i8 @test(i8 %a, i8 %b) {\n"
+      "  %bb = or i8 %a, 241\n"
+      "  %A = call i8 @llvm.usub.sat.i8(i8 %a, i8 %bb)\n"
+      "  ret i8 %A\n"
+      "}\n"
+      "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
+  expectKnownBits(/*zero*/ 240u, /*one*/ 0u);
+}
+
+TEST_F(ComputeKnownBitsTest, ComputeKnownUSubSatZerosPreserved) {
+  // usub.sat(11...011, .1...110)
+  // = ......0.
+  parseAssembly(
+      "define i8 @test(i8 %a, i8 %b) {\n"
+      "  %aa = or i8 %a, 195\n"
+      "  %aaa = and i8 %aa, 251\n"
+      "  %bb = or i8 %b, 70\n"
+      "  %bbb = and i8 %bb, 254\n"
+      "  %A = call i8 @llvm.usub.sat.i8(i8 %aaa, i8 %bbb)\n"
+      "  ret i8 %A\n"
+      "}\n"
+      "declare i8 @llvm.usub.sat.i8(i8, i8)\n");
+  expectKnownBits(/*zero*/ 2u, /*one*/ 0u);
+}
+
+class IsBytewiseValueTest : public ValueTrackingTest,
+                            public ::testing::WithParamInterface<
+                                std::pair<const char *, const char *>> {
+protected:
+};
+
+const std::pair<const char *, const char *> IsBytewiseValueTests[] = {
+    {
+        "i8 0",
+        "i48* null",
+    },
+    {
+        "i8 undef",
+        "i48* undef",
+    },
+    {
+        "i8 0",
+        "i8 zeroinitializer",
+    },
+    {
+        "i8 0",
+        "i8 0",
+    },
+    {
+        "i8 -86",
+        "i8 -86",
+    },
+    {
+        "i8 -1",
+        "i8 -1",
+    },
+    {
+        "i8 undef",
+        "i16 undef",
+    },
+    {
+        "i8 0",
+        "i16 0",
+    },
+    {
+        "",
+        "i16 7",
+    },
+    {
+        "i8 -86",
+        "i16 -21846",
+    },
+    {
+        "i8 -1",
+        "i16 -1",
+    },
+    {
+        "i8 0",
+        "i48 0",
+    },
+    {
+        "i8 -1",
+        "i48 -1",
+    },
+    {
+        "i8 0",
+        "i49 0",
+    },
+    {
+        "",
+        "i49 -1",
+    },
+    {
+        "i8 0",
+        "half 0xH0000",
+    },
+    {
+        "i8 -85",
+        "half 0xHABAB",
+    },
+    {
+        "i8 0",
+        "float 0.0",
+    },
+    {
+        "i8 -1",
+        "float 0xFFFFFFFFE0000000",
+    },
+    {
+        "i8 0",
+        "double 0.0",
+    },
+    {
+        "i8 -15",
+        "double 0xF1F1F1F1F1F1F1F1",
+    },
+    {
+        "i8 undef",
+        "i16* undef",
+    },
+    {
+        "i8 0",
+        "i16* inttoptr (i64 0 to i16*)",
+    },
+    {
+        "i8 -1",
+        "i16* inttoptr (i64 -1 to i16*)",
+    },
+    {
+        "i8 -86",
+        "i16* inttoptr (i64 -6148914691236517206 to i16*)",
+    },
+    {
+        "",
+        "i16* inttoptr (i48 -1 to i16*)",
+    },
+    {
+        "i8 -1",
+        "i16* inttoptr (i96 -1 to i16*)",
+    },
+    {
+        "i8 undef",
+        "[0 x i8] zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "[0 x i8] undef",
+    },
+    {
+        "i8 undef",
+        "[5 x [0 x i8]] zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "[5 x [0 x i8]] undef",
+    },
+    {
+        "i8 0",
+        "[6 x i8] zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "[6 x i8] undef",
+    },
+    {
+        "i8 1",
+        "[5 x i8] [i8 1, i8 1, i8 1, i8 1, i8 1]",
+    },
+    {
+        "",
+        "[5 x i64] [i64 1, i64 1, i64 1, i64 1, i64 1]",
+    },
+    {
+        "i8 -1",
+        "[5 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]",
+    },
+    {
+        "",
+        "[4 x i8] [i8 1, i8 2, i8 1, i8 1]",
+    },
+    {
+        "i8 1",
+        "[4 x i8] [i8 1, i8 undef, i8 1, i8 1]",
+    },
+    {
+        "i8 0",
+        "<6 x i8> zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "<6 x i8> undef",
+    },
+    {
+        "i8 1",
+        "<5 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1>",
+    },
+    {
+        "",
+        "<5 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1>",
+    },
+    {
+        "i8 -1",
+        "<5 x i64> <i64 -1, i64 -1, i64 -1, i64 -1, i64 -1>",
+    },
+    {
+        "",
+        "<4 x i8> <i8 1, i8 1, i8 2, i8 1>",
+    },
+    {
+        "i8 5",
+        "<2 x i8> < i8 5, i8 undef >",
+    },
+    {
+        "i8 0",
+        "[2 x [2 x i16]] zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "[2 x [2 x i16]] undef",
+    },
+    {
+        "i8 -86",
+        "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], "
+        "[2 x i16] [i16 -21846, i16 -21846]]",
+    },
+    {
+        "",
+        "[2 x [2 x i16]] [[2 x i16] [i16 -21846, i16 -21846], "
+        "[2 x i16] [i16 -21836, i16 -21846]]",
+    },
+    {
+        "i8 undef",
+        "{ } zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "{ } undef",
+    },
+    {
+        "i8 undef",
+        "{ {}, {} } zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "{ {}, {} } undef",
+    },
+    {
+        "i8 0",
+        "{i8, i64, i16*} zeroinitializer",
+    },
+    {
+        "i8 undef",
+        "{i8, i64, i16*} undef",
+    },
+    {
+        "i8 -86",
+        "{i8, i64, i16*} {i8 -86, i64 -6148914691236517206, i16* undef}",
+    },
+    {
+        "",
+        "{i8, i64, i16*} {i8 86, i64 -6148914691236517206, i16* undef}",
+    },
+};
+
+INSTANTIATE_TEST_CASE_P(IsBytewiseValueParamTests, IsBytewiseValueTest,
+                        ::testing::ValuesIn(IsBytewiseValueTests),);
+
+TEST_P(IsBytewiseValueTest, IsBytewiseValue) {
+  auto M = parseModule(std::string("@test = global ") + GetParam().second);
+  GlobalVariable *GV = dyn_cast<GlobalVariable>(M->getNamedValue("test"));
+  Value *Actual = isBytewiseValue(GV->getInitializer(), M->getDataLayout());
+  std::string Buff;
+  raw_string_ostream S(Buff);
+  if (Actual)
+    S << *Actual;
+  EXPECT_EQ(GetParam().first, S.str());
+}
diff --git a/src/llvm-project/llvm/unittests/Analysis/VectorUtilsTest.cpp b/src/llvm-project/llvm/unittests/Analysis/VectorUtilsTest.cpp
new file mode 100644
index 0000000..a33fdb5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Analysis/VectorUtilsTest.cpp
@@ -0,0 +1,281 @@
+//===- VectorUtilsTest.cpp - VectorUtils tests ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/NoFolder.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/KnownBits.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class VectorUtilsTest : public testing::Test {
+protected:
+  void parseAssembly(const char *Assembly) {
+    SMDiagnostic Error;
+    M = parseAssemblyString(Assembly, Error, Context);
+
+    std::string errMsg;
+    raw_string_ostream os(errMsg);
+    Error.print("", os);
+
+    // A failure here means that the test itself is buggy.
+    if (!M)
+      report_fatal_error(os.str());
+
+    Function *F = M->getFunction("test");
+    if (F == nullptr)
+      report_fatal_error("Test must have a function named @test");
+
+    A = nullptr;
+    for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+      if (I->hasName()) {
+        if (I->getName() == "A")
+          A = &*I;
+      }
+    }
+    if (A == nullptr)
+      report_fatal_error("@test must have an instruction %A");
+  }
+
+  LLVMContext Context;
+  std::unique_ptr<Module> M;
+  Instruction *A;
+};
+
+struct BasicTest : public testing::Test {
+  LLVMContext Ctx;
+  std::unique_ptr<Module> M;
+  Function *F;
+  BasicBlock *BB;
+  IRBuilder<NoFolder> IRB;
+
+  BasicTest()
+      : M(new Module("VectorUtils", Ctx)),
+        F(Function::Create(
+            FunctionType::get(Type::getVoidTy(Ctx), /* IsVarArg */ false),
+            Function::ExternalLinkage, "f", M.get())),
+        BB(BasicBlock::Create(Ctx, "entry", F)), IRB(BB) {}
+};
+
+
+} // namespace
+
+TEST_F(BasicTest, isSplat) {
+  Value *UndefVec = UndefValue::get(VectorType::get(IRB.getInt8Ty(), 4));
+  EXPECT_TRUE(isSplatValue(UndefVec));
+
+  Constant *UndefScalar = UndefValue::get(IRB.getInt8Ty());
+  EXPECT_FALSE(isSplatValue(UndefScalar));
+
+  Constant *ScalarC = IRB.getInt8(42);
+  EXPECT_FALSE(isSplatValue(ScalarC));
+
+  Constant *OtherScalarC = IRB.getInt8(-42);
+  Constant *NonSplatC = ConstantVector::get({ScalarC, OtherScalarC});
+  EXPECT_FALSE(isSplatValue(NonSplatC));
+
+  Value *SplatC = IRB.CreateVectorSplat(5, ScalarC);
+  EXPECT_TRUE(isSplatValue(SplatC));
+
+  // FIXME: Constant splat analysis does not allow undef elements.
+  Constant *SplatWithUndefC = ConstantVector::get({ScalarC, UndefScalar});
+  EXPECT_FALSE(isSplatValue(SplatWithUndefC));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_00) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> zeroinitializer\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_11) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_01) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 1>\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_FALSE(isSplatValue(A));
+}
+
+// FIXME: Constant (mask) splat analysis does not allow undef elements.
+
+TEST_F(VectorUtilsTest, isSplatValue_0u) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %A = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 undef>\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+      "  %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %A = udiv <2 x i8> %v0, %v1\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop_ConstantOp0) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %A = ashr <2 x i8> <i8 42, i8 42>, %v1\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop_Not_Op0) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 0>\n"
+      "  %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %A = add <2 x i8> %v0, %v1\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Binop_Not_Op1) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i8> %x) {\n"
+      "  %v0 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %v1 = shufflevector <2 x i8> %x, <2 x i8> undef, <2 x i32> <i32 0, i32 1>\n"
+      "  %A = shl <2 x i8> %v0, %v1\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+      "  %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+      "  %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %A = select <2 x i1> %v0, <2 x i8> %v1, <2 x i8> %v2\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_ConstantOp) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+      "  %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %A = select <2 x i1> %v0, <2 x i8> <i8 42, i8 42>, <2 x i8> %v2\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_NotCond) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+      "  %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+      "  %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %A = select <2 x i1> %x, <2 x i8> %v1, <2 x i8> %v2\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_NotOp1) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+      "  %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %A = select <2 x i1> %v0, <2 x i8> %y, <2 x i8> %v2\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_Select_NotOp2) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+      "  %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+      "  %A = select <2 x i1> %v0, <2 x i8> %v1, <2 x i8> %z\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_FALSE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, isSplatValue_SelectBinop) {
+  parseAssembly(
+      "define <2 x i8> @test(<2 x i1> %x, <2 x i8> %y, <2 x i8> %z) {\n"
+      "  %v0 = shufflevector <2 x i1> %x, <2 x i1> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %v1 = shufflevector <2 x i8> %y, <2 x i8> undef, <2 x i32> <i32 0, i32 0>\n"
+      "  %v2 = shufflevector <2 x i8> %z, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  %bo = xor <2 x i8> %v1, %v2\n"
+      "  %A = select <2 x i1> %v0, <2 x i8> %bo, <2 x i8> %v2\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_TRUE(isSplatValue(A));
+}
+
+TEST_F(VectorUtilsTest, getSplatValueElt0) {
+  parseAssembly(
+      "define <2 x i8> @test(i8 %x) {\n"
+      "  %ins = insertelement <2 x i8> undef, i8 %x, i32 0\n"
+      "  %A = shufflevector <2 x i8> %ins, <2 x i8> undef, <2 x i32> zeroinitializer\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_EQ(getSplatValue(A)->getName(), "x");
+}
+
+TEST_F(VectorUtilsTest, getSplatValueEltMismatch) {
+  parseAssembly(
+      "define <2 x i8> @test(i8 %x) {\n"
+      "  %ins = insertelement <2 x i8> undef, i8 %x, i32 1\n"
+      "  %A = shufflevector <2 x i8> %ins, <2 x i8> undef, <2 x i32> zeroinitializer\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_EQ(getSplatValue(A), nullptr);
+}
+
+// TODO: This is a splat, but we don't recognize it.
+
+TEST_F(VectorUtilsTest, getSplatValueElt1) {
+  parseAssembly(
+      "define <2 x i8> @test(i8 %x) {\n"
+      "  %ins = insertelement <2 x i8> undef, i8 %x, i32 1\n"
+      "  %A = shufflevector <2 x i8> %ins, <2 x i8> undef, <2 x i32> <i32 1, i32 1>\n"
+      "  ret <2 x i8> %A\n"
+      "}\n");
+  EXPECT_EQ(getSplatValue(A), nullptr);
+}
diff --git a/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp b/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp
index ddbedd0..d5f734d 100644
--- a/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/AsmParser/AsmParserTest.cpp - asm parser unittests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt b/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt
index 82d76ec..c058402 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/CMakeLists.txt
@@ -5,8 +5,8 @@
 add_llvm_unittest(BinaryFormatTests
   DwarfTest.cpp
   MachOTest.cpp
+  MsgPackDocumentTest.cpp
   MsgPackReaderTest.cpp
-  MsgPackTypesTest.cpp
   MsgPackWriterTest.cpp
   TestFileMagic.cpp
   )
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp
index 08a731f..5509689 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/DwarfTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/BinaryFormat/DwarfTest.cpp - Dwarf support tests ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp
index da8e9e8..5acffc4 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MachOTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/BinaryFormat/MachOTest.cpp - MachO support tests ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackDocumentTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackDocumentTest.cpp
new file mode 100644
index 0000000..00b1579
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackDocumentTest.cpp
@@ -0,0 +1,168 @@
+//===- MsgPackDocumentTest.cpp --------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/MsgPackDocument.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace msgpack;
+
+TEST(MsgPackDocument, TestReadInt) {
+  Document Doc;
+  bool Ok = Doc.readFromBlob(StringRef("\xd0\x00", 2), /*Multi=*/false);
+  ASSERT_TRUE(Ok);
+  ASSERT_EQ(Doc.getRoot().getKind(), Type::Int);
+  ASSERT_EQ(Doc.getRoot().getInt(), 0);
+}
+
+TEST(MsgPackDocument, TestReadArray) {
+  Document Doc;
+  bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
+  ASSERT_TRUE(Ok);
+  ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
+  auto A = Doc.getRoot().getArray();
+  ASSERT_EQ(A.size(), 2u);
+  auto SI = A[0];
+  ASSERT_EQ(SI.getKind(), Type::Int);
+  ASSERT_EQ(SI.getInt(), 1);
+  auto SN = A[1];
+  ASSERT_EQ(SN.getKind(), Type::Nil);
+}
+
+TEST(MsgPackDocument, TestReadMap) {
+  Document Doc;
+  bool Ok = Doc.readFromBlob(StringRef("\x82\xa3"
+                                       "foo"
+                                       "\xd0\x01\xa3"
+                                       "bar"
+                                       "\xd0\x02"),
+                             /*Multi=*/false);
+  ASSERT_TRUE(Ok);
+  ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
+  auto M = Doc.getRoot().getMap();
+  ASSERT_EQ(M.size(), 2u);
+  auto FooS = M["foo"];
+  ASSERT_EQ(FooS.getKind(), Type::Int);
+  ASSERT_EQ(FooS.getInt(), 1);
+  auto BarS = M["bar"];
+  ASSERT_EQ(BarS.getKind(), Type::Int);
+  ASSERT_EQ(BarS.getInt(), 2);
+}
+
+TEST(MsgPackDocument, TestWriteInt) {
+  Document Doc;
+  Doc.getRoot() = Doc.getNode(int64_t(1));
+  std::string Buffer;
+  Doc.writeToBlob(Buffer);
+  ASSERT_EQ(Buffer, "\x01");
+}
+
+TEST(MsgPackDocument, TestWriteArray) {
+  Document Doc;
+  auto A = Doc.getRoot().getArray(/*Convert=*/true);
+  A.push_back(Doc.getNode(int64_t(1)));
+  A.push_back(Doc.getNode());
+  std::string Buffer;
+  Doc.writeToBlob(Buffer);
+  ASSERT_EQ(Buffer, "\x92\x01\xc0");
+}
+
+TEST(MsgPackDocument, TestWriteMap) {
+  Document Doc;
+  auto M = Doc.getRoot().getMap(/*Convert=*/true);
+  M["foo"] = Doc.getNode(int64_t(1));
+  M["bar"] = Doc.getNode(int64_t(2));
+  std::string Buffer;
+  Doc.writeToBlob(Buffer);
+  ASSERT_EQ(Buffer, "\x82\xa3"
+                    "bar"
+                    "\x02\xa3"
+                    "foo"
+                    "\x01");
+}
+
+TEST(MsgPackDocument, TestOutputYAMLArray) {
+  Document Doc;
+  auto A = Doc.getRoot().getArray(/*Convert=*/true);
+  A.push_back(Doc.getNode(int64_t(1)));
+  A.push_back(Doc.getNode(int64_t(2)));
+  std::string Buffer;
+  raw_string_ostream OStream(Buffer);
+  Doc.toYAML(OStream);
+  ASSERT_EQ(OStream.str(), "---\n- 1\n- 2\n...\n");
+}
+
+TEST(MsgPackDocument, TestInputYAMLArray) {
+  Document Doc;
+  bool Ok = Doc.fromYAML("---\n- !int 0x1\n- !str 2\n...\n");
+  ASSERT_TRUE(Ok);
+  ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
+  auto A = Doc.getRoot().getArray();
+  ASSERT_EQ(A.size(), 2u);
+  auto SI = A[0];
+  ASSERT_EQ(SI.getKind(), Type::UInt);
+  ASSERT_EQ(SI.getUInt(), 1u);
+  auto SS = A[1];
+  ASSERT_EQ(SS.getKind(), Type::String);
+  ASSERT_EQ(SS.getString(), "2");
+}
+
+TEST(MsgPackDocument, TestOutputYAMLMap) {
+  Document Doc;
+  auto M = Doc.getRoot().getMap(/*Convert=*/true);
+  M["foo"] = Doc.getNode(int64_t(1));
+  M["bar"] = Doc.getNode(uint64_t(2));
+  auto N = Doc.getMapNode();
+  M["qux"] = N;
+  N["baz"] = Doc.getNode(true);
+  std::string Buffer;
+  raw_string_ostream OStream(Buffer);
+  Doc.toYAML(OStream);
+  ASSERT_EQ(OStream.str(), "---\n"
+                           "bar:             2\n"
+                           "foo:             1\n"
+                           "qux:\n"
+                           "  baz:             true\n"
+                           "...\n");
+}
+
+TEST(MsgPackDocument, TestOutputYAMLMapHex) {
+  Document Doc;
+  Doc.setHexMode();
+  auto M = Doc.getRoot().getMap(/*Convert=*/true);
+  M["foo"] = Doc.getNode(int64_t(1));
+  M["bar"] = Doc.getNode(uint64_t(2));
+  auto N = Doc.getMapNode();
+  M["qux"] = N;
+  N["baz"] = Doc.getNode(true);
+  std::string Buffer;
+  raw_string_ostream OStream(Buffer);
+  Doc.toYAML(OStream);
+  ASSERT_EQ(OStream.str(), "---\n"
+                           "bar:             0x2\n"
+                           "foo:             1\n"
+                           "qux:\n"
+                           "  baz:             true\n"
+                           "...\n");
+}
+
+TEST(MsgPackDocument, TestInputYAMLMap) {
+  Document Doc;
+  bool Ok = Doc.fromYAML("---\nfoo: !int 0x1\nbaz: !str 2\n...\n");
+  ASSERT_TRUE(Ok);
+  ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
+  auto M = Doc.getRoot().getMap();
+  ASSERT_EQ(M.size(), 2u);
+  auto SI = M["foo"];
+  ASSERT_EQ(SI.getKind(), Type::UInt);
+  ASSERT_EQ(SI.getUInt(), 1u);
+  auto SS = M["baz"];
+  ASSERT_EQ(SS.getKind(), Type::String);
+  ASSERT_EQ(SS.getString(), "2");
+}
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp
index e3c1bbb..06ae8b0 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackReaderTest.cpp
@@ -1,9 +1,8 @@
 //===- MsgPackReaderTest.cpp ------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackTypesTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackTypesTest.cpp
deleted file mode 100644
index 87bb6fa..0000000
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackTypesTest.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-//===- MsgPackTypesTest.cpp -------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/BinaryFormat/MsgPackTypes.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-using namespace msgpack;
-
-TEST(MsgPackTypes, TestReadInt) {
-  Reader MPReader(StringRef("\xd0\x00", 2));
-  auto OptNodeOrErr = Node::read(MPReader);
-  ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
-  ASSERT_TRUE(*OptNodeOrErr);
-  auto *S = dyn_cast<ScalarNode>((*OptNodeOrErr)->get());
-  ASSERT_TRUE(S);
-  ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_Int);
-  ASSERT_EQ(S->getInt(), 0);
-}
-
-TEST(MsgPackTypes, TestReadArray) {
-  Reader MPReader(StringRef("\x92\xd0\x01\xc0"));
-  auto OptNodeOrErr = Node::read(MPReader);
-  ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
-  ASSERT_TRUE(*OptNodeOrErr);
-  auto *A = dyn_cast<ArrayNode>((*OptNodeOrErr)->get());
-  ASSERT_TRUE(A);
-  ASSERT_EQ(A->size(), 2u);
-  auto *SI = dyn_cast<ScalarNode>((*A)[0].get());
-  ASSERT_TRUE(SI);
-  ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_Int);
-  ASSERT_EQ(SI->getInt(), 1);
-  auto *SN = dyn_cast<ScalarNode>((*A)[1].get());
-  ASSERT_TRUE(SN);
-  ASSERT_EQ(SN->getScalarKind(), ScalarNode::SK_Nil);
-}
-
-TEST(MsgPackTypes, TestReadMap) {
-  Reader MPReader(StringRef("\x82\xa3"
-                            "foo"
-                            "\xd0\x01\xa3"
-                            "bar"
-                            "\xd0\x02"));
-  auto OptNodeOrErr = Node::read(MPReader);
-  ASSERT_TRUE(static_cast<bool>(OptNodeOrErr));
-  ASSERT_TRUE(*OptNodeOrErr);
-  auto *A = dyn_cast<MapNode>((*OptNodeOrErr)->get());
-  ASSERT_TRUE(A);
-  ASSERT_EQ(A->size(), 2u);
-  auto *FooS = dyn_cast<ScalarNode>((*A)["foo"].get());
-  ASSERT_TRUE(FooS);
-  ASSERT_EQ(FooS->getScalarKind(), ScalarNode::SK_Int);
-  ASSERT_EQ(FooS->getInt(), 1);
-  auto *BarS = dyn_cast<ScalarNode>((*A)["bar"].get());
-  ASSERT_TRUE(BarS);
-  ASSERT_EQ(BarS->getScalarKind(), ScalarNode::SK_Int);
-  ASSERT_EQ(BarS->getInt(), 2);
-}
-
-TEST(MsgPackTypes, TestWriteInt) {
-  std::string Buffer;
-  raw_string_ostream OStream(Buffer);
-  Writer MPWriter(OStream);
-  ScalarNode I(int64_t(1));
-  I.write(MPWriter);
-  ASSERT_EQ(OStream.str(), "\x01");
-}
-
-TEST(MsgPackTypes, TestWriteArray) {
-  std::string Buffer;
-  raw_string_ostream OStream(Buffer);
-  Writer MPWriter(OStream);
-  ArrayNode A;
-  A.push_back(std::make_shared<ScalarNode>(int64_t(1)));
-  A.push_back(std::make_shared<ScalarNode>());
-  A.write(MPWriter);
-  ASSERT_EQ(OStream.str(), "\x92\x01\xc0");
-}
-
-TEST(MsgPackTypes, TestWriteMap) {
-  std::string Buffer;
-  raw_string_ostream OStream(Buffer);
-  Writer MPWriter(OStream);
-  MapNode M;
-  M["foo"] = std::make_shared<ScalarNode>(int64_t(1));
-  M["bar"] = std::make_shared<ScalarNode>(int64_t(2));
-  M.write(MPWriter);
-  ASSERT_EQ(OStream.str(), "\x82\xa3"
-                           "foo"
-                           "\x01\xa3"
-                           "bar"
-                           "\x02");
-}
-
-TEST(MsgPackTypes, TestOutputYAMLArray) {
-  std::string Buffer;
-  raw_string_ostream OStream(Buffer);
-  yaml::Output yout(OStream);
-  ArrayNode A;
-  A.push_back(std::make_shared<ScalarNode>(int64_t(1)));
-  A.push_back(std::make_shared<ScalarNode>(int64_t(2)));
-  yout << A;
-  ASSERT_EQ(OStream.str(), "---\n- !int 1\n- !int 2\n...\n");
-}
-
-TEST(MsgPackTypes, TestInputYAMLArray) {
-  NodePtr RootNode;
-  yaml::Input yin("---\n- !int 1\n- !str 2\n...\n");
-  yin >> RootNode;
-  auto *A = dyn_cast<ArrayNode>(RootNode.get());
-  ASSERT_TRUE(A);
-  ASSERT_EQ(A->size(), 2u);
-  auto *SI = dyn_cast<ScalarNode>((*A)[0].get());
-  ASSERT_TRUE(SI);
-  ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt);
-  ASSERT_EQ(SI->getUInt(), 1u);
-  auto *SS = dyn_cast<ScalarNode>((*A)[1].get());
-  ASSERT_TRUE(SS);
-  ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String);
-  ASSERT_EQ(SS->getString(), "2");
-}
-
-TEST(MsgPackTypes, TestOutputYAMLMap) {
-  std::string Buffer;
-  raw_string_ostream OStream(Buffer);
-  yaml::Output yout(OStream);
-  MapNode M;
-  M["foo"] = std::make_shared<ScalarNode>(int64_t(1));
-  M["bar"] = std::make_shared<ScalarNode>(uint64_t(2));
-  auto N = std::make_shared<MapNode>();
-  (*N)["baz"] = std::make_shared<ScalarNode>(true);
-  M["qux"] = std::move(N);
-  yout << M;
-  ASSERT_EQ(OStream.str(), "---\nfoo:             !int 1\nbar:             "
-                           "!int 2\nqux:             \n  baz:             "
-                           "!bool true\n...\n");
-}
-
-TEST(MsgPackTypes, TestInputYAMLMap) {
-  NodePtr RootNode;
-  yaml::Input yin("---\nfoo: !int 1\nbaz: !str 2\n...\n");
-  yin >> RootNode;
-  auto *M = dyn_cast<MapNode>(RootNode.get());
-  ASSERT_TRUE(M);
-  ASSERT_EQ(M->size(), 2u);
-  auto *SI = dyn_cast<ScalarNode>((*M)["foo"].get());
-  ASSERT_TRUE(SI);
-  ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt);
-  ASSERT_EQ(SI->getUInt(), 1u);
-  auto *SS = dyn_cast<ScalarNode>((*M)["baz"].get());
-  ASSERT_TRUE(SS);
-  ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String);
-  ASSERT_EQ(SS->getString(), "2");
-}
-
-// Test that the document is parsed into a tree of shared_ptr where each node
-// can have multiple owners.
-TEST(MsgPackTypes, TestInputShared) {
-  yaml::Input yin("---\nfoo:\n  bar: !int 1\n...\n");
-  NodePtr InnerMap;
-  NodePtr IntNode;
-  {
-    {
-      {
-        NodePtr RootNode;
-        yin >> RootNode;
-        auto *M = dyn_cast<MapNode>(RootNode.get());
-        ASSERT_TRUE(M);
-        ASSERT_EQ(M->size(), 1u);
-        InnerMap = (*M)["foo"];
-      }
-      auto *N = dyn_cast<MapNode>(InnerMap.get());
-      ASSERT_TRUE(N);
-      ASSERT_EQ(N->size(), 1u);
-      IntNode = (*N)["bar"];
-    }
-    auto *S = dyn_cast<ScalarNode>(IntNode.get());
-    ASSERT_TRUE(S);
-    ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_UInt);
-    ASSERT_EQ(S->getUInt(), 1u);
-  }
-}
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp
index ecca3ee..3a5ba9a 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/MsgPackWriterTest.cpp
@@ -1,9 +1,8 @@
 //===- MsgPackWriterTest.cpp ------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp b/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp
index 5f132ba..22c26df 100644
--- a/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp
+++ b/src/llvm-project/llvm/unittests/BinaryFormat/TestFileMagic.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/BinaryFormat/TestFileMagic.cpp - File magic tests ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp b/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp
index 3b46007..e803677 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Bitcode/BitReaderTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt b/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt
index 4d06f80..7e9d1bc 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Bitcode/CMakeLists.txt
@@ -8,6 +8,4 @@
 
 add_llvm_unittest(BitcodeTests
   BitReaderTest.cpp
-  BitstreamReaderTest.cpp
-  BitstreamWriterTest.cpp
   )
diff --git a/src/llvm-project/llvm/unittests/Bitcode/BitstreamReaderTest.cpp b/src/llvm-project/llvm/unittests/Bitstream/BitstreamReaderTest.cpp
similarity index 71%
rename from src/llvm-project/llvm/unittests/Bitcode/BitstreamReaderTest.cpp
rename to src/llvm-project/llvm/unittests/Bitstream/BitstreamReaderTest.cpp
index e7535f3..f58af22 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/BitstreamReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Bitstream/BitstreamReaderTest.cpp
@@ -1,15 +1,14 @@
 //===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Bitstream/BitstreamReader.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitstream/BitstreamWriter.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -23,15 +22,17 @@
   BitstreamCursor Cursor(Bytes);
 
   EXPECT_FALSE(Cursor.AtEndOfStream());
-  (void)Cursor.Read(8);
+  Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(8);
+  EXPECT_TRUE((bool)MaybeRead);
   EXPECT_FALSE(Cursor.AtEndOfStream());
-  (void)Cursor.Read(24);
+  MaybeRead = Cursor.Read(24);
+  EXPECT_TRUE((bool)MaybeRead);
   EXPECT_TRUE(Cursor.AtEndOfStream());
 
-  Cursor.JumpToBit(0);
+  EXPECT_FALSE(Cursor.JumpToBit(0));
   EXPECT_FALSE(Cursor.AtEndOfStream());
 
-  Cursor.JumpToBit(32);
+  EXPECT_FALSE(Cursor.JumpToBit(32));
   EXPECT_TRUE(Cursor.AtEndOfStream());
 }
 
@@ -41,7 +42,7 @@
   };
   BitstreamCursor Cursor(Bytes);
 
-  Cursor.JumpToBit(32);
+  EXPECT_FALSE(Cursor.JumpToBit(32));
   EXPECT_TRUE(Cursor.AtEndOfStream());
 }
 
@@ -57,7 +58,8 @@
 
   for (unsigned I = 0, E = 32; I != E; ++I) {
     EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
-    (void)Cursor.Read(1);
+    Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(1);
+    EXPECT_TRUE((bool)MaybeRead);
   }
   EXPECT_EQ(4u, Cursor.getCurrentByteNo());
 }
@@ -117,24 +119,33 @@
 
     // Header.  Included in test so that we can run llvm-bcanalyzer to debug
     // when there are problems.
-    ASSERT_EQ(Magic, Stream.Read(32));
+    Expected<SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(32);
+    ASSERT_TRUE((bool)MaybeRead);
+    ASSERT_EQ(Magic, MaybeRead.get());
 
     // Block.
-    BitstreamEntry Entry =
+    Expected<BitstreamEntry> MaybeEntry =
         Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
+    ASSERT_TRUE((bool)MaybeEntry);
+    BitstreamEntry Entry = MaybeEntry.get();
     ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
     ASSERT_EQ(BlockID, Entry.ID);
     ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
 
     // Abbreviation.
-    Entry = Stream.advance();
+    MaybeEntry = Stream.advance();
+    ASSERT_TRUE((bool)MaybeEntry);
+    Entry = MaybeEntry.get();
     ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
     ASSERT_EQ(AbbrevID, Entry.ID);
 
     // Record.
     StringRef BlobOut;
     SmallVector<uint64_t, 1> Record;
-    ASSERT_EQ(RecordID, Stream.readRecord(Entry.ID, Record, &BlobOut));
+    Expected<unsigned> MaybeRecord =
+        Stream.readRecord(Entry.ID, Record, &BlobOut);
+    ASSERT_TRUE((bool)MaybeRecord);
+    ASSERT_EQ(RecordID, MaybeRecord.get());
     EXPECT_TRUE(Record.empty());
     EXPECT_EQ(BlobIn, BlobOut);
   }
@@ -144,8 +155,13 @@
   uint8_t Bytes[] = {8, 7, 6, 5, 4, 3, 2, 1};
   for (unsigned I = 1; I != 8; ++I) {
     SimpleBitstreamCursor Cursor(ArrayRef<uint8_t>(Bytes, I));
-    EXPECT_EQ(8ull, Cursor.Read(8));
+    Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(8);
+    ASSERT_TRUE((bool)MaybeRead);
+    EXPECT_EQ(8ull, MaybeRead.get());
   }
 }
 
+static_assert(is_trivially_copyable<BitCodeAbbrevOp>::value,
+              "trivially copyable");
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Bitcode/BitstreamWriterTest.cpp b/src/llvm-project/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
similarity index 83%
rename from src/llvm-project/llvm/unittests/Bitcode/BitstreamWriterTest.cpp
rename to src/llvm-project/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
index 79143c8..993c5aa 100644
--- a/src/llvm-project/llvm/unittests/Bitcode/BitstreamWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
@@ -1,13 +1,12 @@
 //===- BitstreamWriterTest.cpp - Tests for BitstreamWriter ----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitstream/BitstreamWriter.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "gtest/gtest.h"
diff --git a/src/llvm-project/llvm/unittests/Bitstream/CMakeLists.txt b/src/llvm-project/llvm/unittests/Bitstream/CMakeLists.txt
new file mode 100644
index 0000000..a620034
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Bitstream/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(LLVM_LINK_COMPONENTS
+  BitstreamReader
+  )
+
+add_llvm_unittest(BitstreamTests
+  BitstreamReaderTest.cpp
+  BitstreamWriterTest.cpp
+  )
diff --git a/src/llvm-project/llvm/unittests/CMakeLists.txt b/src/llvm-project/llvm/unittests/CMakeLists.txt
index 459e89d..6bb2fb8 100644
--- a/src/llvm-project/llvm/unittests/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/CMakeLists.txt
@@ -13,6 +13,7 @@
 add_subdirectory(AsmParser)
 add_subdirectory(BinaryFormat)
 add_subdirectory(Bitcode)
+add_subdirectory(Bitstream)
 add_subdirectory(CodeGen)
 add_subdirectory(DebugInfo)
 add_subdirectory(Demangle)
@@ -26,7 +27,7 @@
 add_subdirectory(Object)
 add_subdirectory(ObjectYAML)
 add_subdirectory(Option)
-add_subdirectory(OptRemarks)
+add_subdirectory(Remarks)
 add_subdirectory(Passes)
 add_subdirectory(ProfileData)
 add_subdirectory(Support)
diff --git a/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
index e25249e..3ac32ae 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.cpp -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -158,4 +157,46 @@
             false);
 }
 
+// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
+TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
+  if (!TM)
+    return;
+  SDLoc Loc;
+  auto IntVT = EVT::getIntegerVT(Context, 8);
+  auto UnknownOp = DAG->getRegister(0, IntVT);
+  auto Mask = DAG->getConstant(0x8A, Loc, IntVT);
+  auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
+  auto N1 = DAG->getConstant(0x55, Loc, IntVT);
+  auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);
+  // N0 = ?000?0?0
+  // N1 = 01010101
+  //  =>
+  // Known.One  = 01010101 (0x55)
+  // Known.Zero = 00100000 (0x20)
+  KnownBits Known = DAG->computeKnownBits(Op);
+  EXPECT_EQ(Known.Zero, APInt(8, 0x20));
+  EXPECT_EQ(Known.One, APInt(8, 0x55));
+}
+
+// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
+TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
+  if (!TM)
+    return;
+  SDLoc Loc;
+  auto IntVT = EVT::getIntegerVT(Context, 8);
+  auto N0 = DAG->getConstant(0x55, Loc, IntVT);
+  auto UnknownOp = DAG->getRegister(0, IntVT);
+  auto Mask = DAG->getConstant(0x2e, Loc, IntVT);
+  auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);
+  auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);
+  // N0 = 01010101
+  // N1 = 00?0???0
+  //  =>
+  // Known.One  = 00000001 (0x1)
+  // Known.Zero = 10000000 (0x80)
+  KnownBits Known = DAG->computeKnownBits(Op);
+  EXPECT_EQ(Known.Zero, APInt(8, 0x80));
+  EXPECT_EQ(Known.One, APInt(8, 0x1));
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt b/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt
index 5ef8c2a..706a65b 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/CodeGen/CMakeLists.txt
@@ -19,6 +19,8 @@
   MachineInstrTest.cpp
   MachineOperandTest.cpp
   ScalableVectorMVTsTest.cpp
+  TypeTraitsTest.cpp
+  TargetOptionsTest.cpp
   )
 
 add_subdirectory(GlobalISel)
diff --git a/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp
index c82876b..649e132 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/DIEHashTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/CodeGen/DIEHashTest.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt
index 32bbd56..2ffec27 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CMakeLists.txt
@@ -10,8 +10,10 @@
   )
 
 add_llvm_unittest(GlobalISelTests
-        LegalizerInfoTest.cpp
-        PatternMatchTest.cpp
-        LegalizerHelperTest.cpp
-        CSETest.cpp
-        )
+  CSETest.cpp
+  LegalizerHelperTest.cpp
+  LegalizerInfoTest.cpp
+  MachineIRBuilderTest.cpp
+  GISelMITest.cpp
+  PatternMatchTest.cpp
+  )
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
index c6bbd8b..f2f755b 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
@@ -1,9 +1,8 @@
 //===- CSETest.cpp -----------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -22,43 +21,56 @@
   auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]});
   auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
   GISelCSEInfo CSEInfo;
-  CSEInfo.setCSEConfig(make_unique<CSEConfig>());
+  CSEInfo.setCSEConfig(make_unique<CSEConfigFull>());
   CSEInfo.analyze(*MF);
   B.setCSEInfo(&CSEInfo);
   CSEMIRBuilder CSEB(B.getState());
+
   CSEB.setInsertPt(*EntryMBB, EntryMBB->begin());
   unsigned AddReg = MRI->createGenericVirtualRegister(s16);
   auto MIBAddCopy =
       CSEB.buildInstr(TargetOpcode::G_ADD, {AddReg}, {MIBInput, MIBInput});
-  ASSERT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY);
+  EXPECT_EQ(MIBAddCopy->getOpcode(), TargetOpcode::COPY);
   auto MIBAdd2 =
       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
-  ASSERT_TRUE(&*MIBAdd == &*MIBAdd2);
+  EXPECT_TRUE(&*MIBAdd == &*MIBAdd2);
   auto MIBAdd4 =
       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
-  ASSERT_TRUE(&*MIBAdd == &*MIBAdd4);
+  EXPECT_TRUE(&*MIBAdd == &*MIBAdd4);
   auto MIBAdd5 =
       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput1});
-  ASSERT_TRUE(&*MIBAdd != &*MIBAdd5);
+  EXPECT_TRUE(&*MIBAdd != &*MIBAdd5);
 
   // Try building G_CONSTANTS.
   auto MIBCst = CSEB.buildConstant(s32, 0);
   auto MIBCst1 = CSEB.buildConstant(s32, 0);
-  ASSERT_TRUE(&*MIBCst == &*MIBCst1);
+  EXPECT_TRUE(&*MIBCst == &*MIBCst1);
   // Try the CFing of BinaryOps.
   auto MIBCF1 = CSEB.buildInstr(TargetOpcode::G_ADD, {s32}, {MIBCst, MIBCst});
-  ASSERT_TRUE(&*MIBCF1 == &*MIBCst);
+  EXPECT_TRUE(&*MIBCF1 == &*MIBCst);
 
   // Try out building FCONSTANTs.
   auto MIBFP0 = CSEB.buildFConstant(s32, 1.0);
   auto MIBFP0_1 = CSEB.buildFConstant(s32, 1.0);
-  ASSERT_TRUE(&*MIBFP0 == &*MIBFP0_1);
+  EXPECT_TRUE(&*MIBFP0 == &*MIBFP0_1);
   CSEInfo.print();
 
+  // Make sure buildConstant with a vector type doesn't crash, and the elements
+  // CSE.
+  auto Splat0 = CSEB.buildConstant(LLT::vector(2, s32), 0);
+  EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, Splat0->getOpcode());
+  EXPECT_EQ(Splat0->getOperand(1).getReg(), Splat0->getOperand(2).getReg());
+  EXPECT_EQ(&*MIBCst, MRI->getVRegDef(Splat0->getOperand(1).getReg()));
+
+  auto FSplat = CSEB.buildFConstant(LLT::vector(2, s32), 1.0);
+  EXPECT_EQ(TargetOpcode::G_BUILD_VECTOR, FSplat->getOpcode());
+  EXPECT_EQ(FSplat->getOperand(1).getReg(), FSplat->getOperand(2).getReg());
+  EXPECT_EQ(&*MIBFP0, MRI->getVRegDef(FSplat->getOperand(1).getReg()));
+
   // Check G_UNMERGE_VALUES
   auto MIBUnmerge = CSEB.buildUnmerge({s32, s32}, Copies[0]);
   auto MIBUnmerge2 = CSEB.buildUnmerge({s32, s32}, Copies[0]);
-  ASSERT_TRUE(&*MIBUnmerge == &*MIBUnmerge2);
+  EXPECT_TRUE(&*MIBUnmerge == &*MIBUnmerge2);
 }
 
 TEST_F(GISelMITest, TestCSEConstantConfig) {
@@ -78,10 +90,10 @@
   auto MIBAdd1 =
       CSEB.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
   // We should CSE constants only. Adds should not be CSEd.
-  ASSERT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
-  ASSERT_TRUE(&*MIBAdd1 != &*MIBAdd);
+  EXPECT_TRUE(MIBAdd1->getOpcode() != TargetOpcode::COPY);
+  EXPECT_TRUE(&*MIBAdd1 != &*MIBAdd);
   // We should CSE constant.
   auto MIBZeroTmp = CSEB.buildConstant(s16, 0);
-  ASSERT_TRUE(&*MIBZero == &*MIBZeroTmp);
+  EXPECT_TRUE(&*MIBZero == &*MIBZeroTmp);
 }
 } // namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp
new file mode 100644
index 0000000..0558c41
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp
@@ -0,0 +1,30 @@
+//===------------------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GISelMITest.h"
+
+namespace llvm {
+std::ostream &
+operator<<(std::ostream &OS, const LLT Ty) {
+  std::string Repr;
+  raw_string_ostream SS{Repr};
+  Ty.print(SS);
+  OS << SS.str();
+  return OS;
+}
+
+std::ostream &
+operator<<(std::ostream &OS, const MachineFunction &MF) {
+  std::string Repr;
+  raw_string_ostream SS{Repr};
+  MF.print(SS);
+  OS << SS.str();
+  return OS;
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
index 91b8e81..0e18ac8 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
@@ -1,10 +1,8 @@
-//===- GISelMITest.h
-//-----------------------------------------------===//
+//===- GISelMITest.h --------------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #ifndef LLVM_UNITTEST_CODEGEN_GLOBALISEL_GISELMI_H
@@ -45,6 +43,15 @@
   initializeCodeGen(*Registry);
 }
 
+// Define a printers to help debugging when things go wrong.
+namespace llvm {
+std::ostream &
+operator<<(std::ostream &OS, const LLT Ty);
+
+std::ostream &
+operator<<(std::ostream &OS, const MachineFunction &MF);
+}
+
 /// Create a TargetMachine. As we lack a dedicated always available target for
 /// unittests, we go for "AArch64".
 static std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
@@ -117,7 +124,7 @@
   return MF;
 }
 
-static void collectCopies(SmallVectorImpl<unsigned> &Copies,
+static void collectCopies(SmallVectorImpl<Register> &Copies,
                           MachineFunction *MF) {
   for (auto &MBB : *MF)
     for (MachineInstr &MI : MBB) {
@@ -145,7 +152,7 @@
   MachineFunction *MF;
   std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>>
       ModuleMMIPair;
-  SmallVector<unsigned, 4> Copies;
+  SmallVector<Register, 4> Copies;
   MachineBasicBlock *EntryMBB;
   MachineIRBuilder B;
   MachineRegisterInfo *MRI;
@@ -188,7 +195,9 @@
                         SMLoc());
   Regex PrefixRE = FC.buildCheckPrefixRegex();
   std::vector<FileCheckString> CheckStrings;
-  FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings);
+  if (FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings))
+    return false;
+
   auto OutBuffer = OutputBuf->getBuffer();
   SM.AddNewSourceBuffer(std::move(OutputBuf), SMLoc());
   return FC.CheckInput(SM, OutBuffer, CheckStrings);
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index 9764a0b..2776f75 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -1,15 +1,18 @@
 //===- LegalizerHelperTest.cpp
 //-----------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "GISelMITest.h"
 
+using namespace LegalizeActions;
+using namespace LegalizeMutations;
+using namespace LegalityPredicates;
+
 namespace {
 
 class DummyGISelObserver : public GISelChangeObserver {
@@ -27,8 +30,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(
-      A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s64}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s64, s64}});
+  });
   // Build Instr
   auto MIBCTTZ =
       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
@@ -36,7 +40,7 @@
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
   // Perform Legalization
-  ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+  EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -48,7 +52,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTTZ expansion in terms of CTLZ
@@ -57,8 +61,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(A,
-                      { getActionDefinitionsBuilder(G_CTLZ).legalFor({s64}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}});
+  });
   // Build Instr
   auto MIBCTTZ =
       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
@@ -66,7 +71,7 @@
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
   // Perform Legalization
-  ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+  EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -80,7 +85,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTTZ expansion in terms of CTPOP
@@ -89,15 +94,16 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(
-      A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s64}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}});
+  });
   // Build
   auto MIBCTTZ =
       B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+  EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -109,7 +115,72 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+// CTPOP widening.
+TEST_F(GISelMITest, WidenBitCountingCTPOP1) {
+  if (!TM)
+    return;
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+      getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
+    });
+
+  // Build
+  // Trunc it to s8.
+  LLT s8{LLT::scalar(8)};
+  LLT s16{LLT::scalar(16)};
+  auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+  auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s16}, {MIBTrunc});
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.widenScalar(*MIBCTPOP, 1, s16));
+
+  auto CheckStr = R"(
+  CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
+  CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
+  CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
+  CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]]:_(s16)
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+// Test a strange case where the result is wider than the source
+TEST_F(GISelMITest, WidenBitCountingCTPOP2) {
+  if (!TM)
+    return;
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+      getActionDefinitionsBuilder(G_CTPOP).legalFor({{s32, s16}});
+    });
+
+  // Build
+  // Trunc it to s8.
+  LLT s8{LLT::scalar(8)};
+  LLT s16{LLT::scalar(16)};
+  LLT s32{LLT::scalar(32)};
+  auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+  auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s32}, {MIBTrunc});
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.widenScalar(*MIBCTPOP, 1, s16));
+
+  auto CheckStr = R"(
+  CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)
+  CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)
+  CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]
+  CHECK: [[COPY:%[0-9]+]]:_(s32) = G_ZEXT [[CTPOP]]:_(s16)
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTTZ_ZERO_UNDEF expansion in terms of CTTZ
@@ -118,15 +189,16 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(A,
-                      { getActionDefinitionsBuilder(G_CTTZ).legalFor({s64}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}});
+  });
   // Build
   auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF,
                               {LLT::scalar(64)}, {Copies[0]});
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
+  EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -134,7 +206,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF
@@ -143,15 +215,16 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(
-      A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s64}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}});
+  });
   // Build
   auto MIBCTLZ =
       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
+  EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -163,7 +236,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall
@@ -172,15 +245,16 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(
-      A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({s64}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s64, s64}});
+  });
   // Build
   auto MIBCTLZ =
       B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
+  EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -192,7 +266,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTLZ expansion
@@ -201,8 +275,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(A,
-                      { getActionDefinitionsBuilder(G_CTPOP).legalFor({s8}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -211,7 +286,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
+  EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -231,7 +306,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTLZ widening.
@@ -240,8 +315,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(A,
-                      { getActionDefinitionsBuilder(G_CTLZ).legalFor({s16}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -251,7 +327,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ, 0, s16) ==
+  EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -264,7 +340,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTLZ_ZERO_UNDEF widening.
@@ -273,8 +349,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(
-      A, { getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({s16}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -285,7 +362,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 0, s16) ==
+  EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -298,7 +375,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTPOP widening.
@@ -307,8 +384,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(
-      A, { getActionDefinitionsBuilder(G_CTPOP).legalFor({s16}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -318,7 +396,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.widenScalar(*MIBCTPOP, 0, s16) ==
+  EXPECT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -329,7 +407,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTTZ_ZERO_UNDEF widening.
@@ -338,8 +416,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(
-      A, { getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({s16}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -350,7 +429,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 0, s16) ==
+  EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -361,7 +440,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // CTTZ widening.
@@ -370,8 +449,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(A,
-                      { getActionDefinitionsBuilder(G_CTTZ).legalFor({s16}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -381,7 +461,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.widenScalar(*MIBCTTZ, 0, s16) ==
+  EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -394,7 +474,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 // UADDO widening.
 TEST_F(GISelMITest, WidenUADDO) {
@@ -402,8 +482,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(A,
-                      { getActionDefinitionsBuilder(G_ADD).legalFor({s16}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -415,7 +496,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
+  EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -430,7 +511,7 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
 // USUBO widening.
@@ -439,8 +520,9 @@
     return;
 
   // Declare your legalization info
-  DefineLegalizerInfo(A,
-                      { getActionDefinitionsBuilder(G_SUB).legalFor({s16}); });
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});
+  });
   // Build
   // Trunc it to s8.
   LLT s8{LLT::scalar(8)};
@@ -452,7 +534,7 @@
   AInfo Info(MF->getSubtarget());
   DummyGISelObserver Observer;
   LegalizerHelper Helper(*MF, Info, Observer, B);
-  ASSERT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
+  EXPECT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==
               LegalizerHelper::LegalizeResult::Legalized);
 
   auto CheckStr = R"(
@@ -467,6 +549,460 @@
   )";
 
   // Check
-  ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, FewerElementsAnd) {
+  if (!TM)
+    return;
+
+  const LLT V2S32 = LLT::vector(2, 32);
+  const LLT V5S32 = LLT::vector(5, 32);
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_AND)
+      .legalFor({s32});
+  });
+
+  auto Op0 = B.buildUndef(V5S32);
+  auto Op1 = B.buildUndef(V5S32);
+  auto And = B.buildAnd(V5S32, Op0, Op1);
+
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_TRUE(Helper.fewerElementsVector(*And, 0, V2S32) ==
+              LegalizerHelper::LegalizeResult::Legalized);
+
+  auto CheckStr = R"(
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[IMP_DEF2:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF0]]:_(<5 x s32>), 0
+  CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF1]]:_(<5 x s32>), 0
+  CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[EXTRACT0]]:_, [[EXTRACT1]]:_
+  CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[IMP_DEF2]]:_, [[AND0]]:_(<2 x s32>), 0
+
+  CHECK: [[EXTRACT2:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF0]]:_(<5 x s32>), 64
+  CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[IMP_DEF1]]:_(<5 x s32>), 64
+  CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[EXTRACT2]]:_, [[EXTRACT3]]:_
+  CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[AND1]]:_(<2 x s32>), 64
+
+  CHECK: [[EXTRACT4:%[0-9]+]]:_(s32) = G_EXTRACT [[IMP_DEF0]]:_(<5 x s32>), 128
+  CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[IMP_DEF1]]:_(<5 x s32>), 128
+  CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[EXTRACT4]]:_, [[EXTRACT5]]:_
+  CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[AND2]]:_(s32), 128
+  )";
+
+  // Check
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, MoreElementsAnd) {
+  if (!TM)
+    return;
+
+  LLT s32 = LLT::scalar(32);
+  LLT v2s32 = LLT::vector(2, 32);
+  LLT v6s32 = LLT::vector(6, 32);
+
+  LegalizerInfo LI;
+  LI.getActionDefinitionsBuilder(TargetOpcode::G_AND)
+    .legalFor({v6s32})
+    .clampMinNumElements(0, s32, 6);
+  LI.computeTables();
+
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, LI, Observer, B);
+
+  B.setInsertPt(*EntryMBB, EntryMBB->end());
+
+  auto Val0 = B.buildBitcast(v2s32, Copies[0]);
+  auto Val1 = B.buildBitcast(v2s32, Copies[1]);
+
+  auto And = B.buildAnd(v2s32, Val0, Val1);
+
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.moreElementsVector(*And, 0, v6s32));
+
+  auto CheckStr = R"(
+  CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
+  CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST
+  CHECK: [[IMP_DEF0:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[CONCAT0:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>), [[IMP_DEF0]]:_(<2 x s32>)
+  CHECK: [[IMP_DEF1:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[CONCAT1:%[0-9]+]]:_(<6 x s32>) = G_CONCAT_VECTORS [[BITCAST1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>), [[IMP_DEF1]]:_(<2 x s32>)
+  CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[CONCAT0]]:_, [[CONCAT1]]:_
+  CHECK: (<2 x s32>) = G_EXTRACT [[AND]]:_(<6 x s32>), 0
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, FewerElementsPhi) {
+  if (!TM)
+    return;
+
+  LLT s1 = LLT::scalar(1);
+  LLT s32 = LLT::scalar(32);
+  LLT s64 = LLT::scalar(64);
+  LLT v2s32 = LLT::vector(2, 32);
+  LLT v5s32 = LLT::vector(5, 32);
+
+  LegalizerInfo LI;
+  LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)
+    .legalFor({v2s32})
+    .clampMinNumElements(0, s32, 2);
+  LI.computeTables();
+
+  LLT PhiTy = v5s32;
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, LI, Observer, B);
+  B.setMBB(*EntryMBB);
+
+  MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock();
+  MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock();
+  MF->insert(MF->end(), MidMBB);
+  MF->insert(MF->end(), EndMBB);
+
+  EntryMBB->addSuccessor(MidMBB);
+  EntryMBB->addSuccessor(EndMBB);
+  MidMBB->addSuccessor(EndMBB);
+
+  auto InitVal = B.buildUndef(PhiTy);
+  auto InitOtherVal = B.buildConstant(s64, 999);
+
+  auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
+  B.buildBrCond(ICmp.getReg(0), *MidMBB);
+  B.buildBr(*EndMBB);
+
+
+  B.setMBB(*MidMBB);
+  auto MidVal = B.buildUndef(PhiTy);
+  auto MidOtherVal = B.buildConstant(s64, 345);
+  B.buildBr(*EndMBB);
+
+  B.setMBB(*EndMBB);
+  auto Phi = B.buildInstr(TargetOpcode::G_PHI)
+    .addDef(MRI->createGenericVirtualRegister(PhiTy))
+    .addUse(InitVal.getReg(0))
+    .addMBB(EntryMBB)
+    .addUse(MidVal.getReg(0))
+    .addMBB(MidMBB);
+
+  // Insert another irrelevant phi to make sure the rebuild is inserted after
+  // it.
+  B.buildInstr(TargetOpcode::G_PHI)
+    .addDef(MRI->createGenericVirtualRegister(s64))
+    .addUse(InitOtherVal.getReg(0))
+    .addMBB(EntryMBB)
+    .addUse(MidOtherVal.getReg(0))
+    .addMBB(MidMBB);
+
+  // Add some use instruction after the phis.
+  B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0));
+
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.fewerElementsVector(*Phi, 0, v2s32));
+
+  auto CheckStr = R"(
+  CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 0
+  CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 64
+  CHECK: [[EXTRACT2:%[0-9]+]]:_(s32) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 128
+  CHECK: G_BRCOND
+
+  CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 0
+  CHECK: [[EXTRACT4:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 64
+  CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 128
+  CHECK: G_BR
+
+  CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT0]]:_(<2 x s32>), %bb.0, [[EXTRACT3]]:_(<2 x s32>), %bb.1
+  CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT1]]:_(<2 x s32>), %bb.0, [[EXTRACT4]]:_(<2 x s32>), %bb.1
+  CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[EXTRACT2]]:_(s32), %bb.0, [[EXTRACT5]]:_(s32), %bb.1
+
+  CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI
+  CHECK: [[REBUILD_VAL_IMPDEF:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[REBUILD_VAL_IMPDEF]]:_, [[PHI0]]:_(<2 x s32>), 0
+  CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[PHI1]]:_(<2 x s32>), 64
+  CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[PHI2]]:_(s32), 128
+  CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[INSERT2]]:_, [[INSERT2]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+// FNEG expansion in terms of FSUB
+TEST_F(GISelMITest, LowerFNEG) {
+  if (!TM)
+    return;
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_FSUB).legalFor({s64});
+  });
+
+  // Build Instr. Make sure FMF are preserved.
+  auto FAdd =
+    B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]},
+                 MachineInstr::MIFlag::FmNsz);
+
+  // Should not propagate the flags of src instruction.
+  auto FNeg0 =
+    B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)},
+                 {MachineInstr::MIFlag::FmArcp});
+
+  // Preserve the one flag.
+  auto FNeg1 =
+    B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]},
+                 MachineInstr::MIFlag::FmNoInfs);
+
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  // Perform Legalization
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*FNeg0, 0, LLT::scalar(64)));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*FNeg1, 0, LLT::scalar(64)));
+
+  auto CheckStr = R"(
+  CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_
+  CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_FCONSTANT double -0.000000e+00
+  CHECK: [[FSUB0:%[0-9]+]]:_(s64) = arcp G_FSUB [[CONST0]]:_, [[FADD]]:_
+  CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_FCONSTANT double -0.000000e+00
+  CHECK: [[FSUB1:%[0-9]+]]:_(s64) = ninf G_FSUB [[CONST1]]:_, %0:_
+  )";
+
+  // Check
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, LowerMinMax) {
+  if (!TM)
+    return;
+
+  LLT s64 = LLT::scalar(64);
+  LLT v2s32 = LLT::vector(2, 32);
+
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
+      .lowerFor({s64, LLT::vector(2, s32)});
+  });
+
+  auto SMin = B.buildSMin(s64, Copies[0], Copies[1]);
+  auto SMax = B.buildSMax(s64, Copies[0], Copies[1]);
+  auto UMin = B.buildUMin(s64, Copies[0], Copies[1]);
+  auto UMax = B.buildUMax(s64, Copies[0], Copies[1]);
+
+  auto VecVal0 = B.buildBitcast(v2s32, Copies[0]);
+  auto VecVal1 = B.buildBitcast(v2s32, Copies[1]);
+
+  auto SMinV = B.buildSMin(v2s32, VecVal0, VecVal1);
+  auto SMaxV = B.buildSMax(v2s32, VecVal0, VecVal1);
+  auto UMinV = B.buildUMin(v2s32, VecVal0, VecVal1);
+  auto UMaxV = B.buildUMax(v2s32, VecVal0, VecVal1);
+
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*SMin, 0, s64));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*SMax, 0, s64));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*UMin, 0, s64));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*UMax, 0, s64));
+
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*SMinV, 0, v2s32));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*SMaxV, 0, v2s32));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*UMinV, 0, v2s32));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.lower(*UMaxV, 0, v2s32));
+
+  auto CheckStr = R"(
+  CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_
+  CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_
+
+  CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_
+  CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_
+
+  CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_
+  CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_
+
+  CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_
+  CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_
+
+  CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64)
+  CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64)
+
+  CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+  CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+
+  CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+  CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+
+  CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+  CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+
+  CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_
+  CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, WidenScalarBuildVector) {
+  if (!TM)
+    return;
+
+  LLT S32 = LLT::scalar(32);
+  LLT S16 = LLT::scalar(16);
+  LLT V2S16 = LLT::vector(2, S16);
+  LLT V2S32 = LLT::vector(2, S32);
+
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})
+      .lowerFor({s64, LLT::vector(2, s32)});
+  });
+
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  B.setInsertPt(*EntryMBB, EntryMBB->end());
+
+  Register Constant0 = B.buildConstant(S16, 1).getReg(0);
+  Register Constant1 = B.buildConstant(S16, 2).getReg(0);
+  auto BV0 = B.buildBuildVector(V2S16, {Constant0, Constant1});
+  auto BV1 = B.buildBuildVector(V2S16, {Constant0, Constant1});
+
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.widenScalar(*BV0, 0, V2S32));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.widenScalar(*BV1, 1, S32));
+
+  auto CheckStr = R"(
+  CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
+  CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
+  CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
+  CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
+  CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32)
+  CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]]
+
+  CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]
+  CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]
+
+  CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32)
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, LowerMergeValues) {
+  if (!TM)
+    return;
+
+  const LLT S32 = LLT::scalar(32);
+  const LLT S24 = LLT::scalar(24);
+  const LLT S21 = LLT::scalar(21);
+  const LLT S16 = LLT::scalar(16);
+  const LLT S9 = LLT::scalar(9);
+  const LLT S8 = LLT::scalar(8);
+  const LLT S3 = LLT::scalar(3);
+
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_UNMERGE_VALUES)
+      .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9)));
+  });
+
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  B.setInsertPt(*EntryMBB, EntryMBB->end());
+
+  // 24 = 3 3 3   3 3 3   3 3
+  //     => 9
+  //
+  // This can do 3 merges, but need an extra implicit_def.
+  SmallVector<Register, 8> Merge0Ops;
+  for (int I = 0; I != 8; ++I)
+    Merge0Ops.push_back(B.buildConstant(S3, I).getReg(0));
+
+  auto Merge0 = B.buildMerge(S24, Merge0Ops);
+
+  // 21 = 3 3 3   3 3 3   3
+  //     => 9, 2 extra implicit_def needed
+  //
+  SmallVector<Register, 8> Merge1Ops;
+  for (int I = 0; I != 7; ++I)
+    Merge1Ops.push_back(B.buildConstant(S3, I).getReg(0));
+
+  auto Merge1 = B.buildMerge(S21, Merge1Ops);
+
+  SmallVector<Register, 8> Merge2Ops;
+  for (int I = 0; I != 2; ++I)
+    Merge2Ops.push_back(B.buildConstant(S8, I).getReg(0));
+
+    auto Merge2 = B.buildMerge(S16, Merge2Ops);
+
+
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.widenScalar(*Merge0, 1, S9));
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.widenScalar(*Merge1, 1, S9));
+
+  // Request a source size greater than the original destination size.
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.widenScalar(*Merge2, 1, S32));
+
+  auto CheckStr = R"(
+  CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
+  CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
+  CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
+  CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
+  CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
+  CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
+  CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
+  CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -1
+  CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
+  CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)
+  CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)
+  CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)
+  CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9)
+  CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27)
+
+
+  CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 0
+  CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 1
+  CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 2
+  CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 3
+  CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -4
+  CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -3
+  CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -2
+  CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF
+  CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)
+  CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)
+  CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)
+  CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9)
+  CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27)
+
+
+  CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
+  CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 1
+  CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8)
+  CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8)
+  [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
+  [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32)
+  [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_
+  (s16) = G_TRUNC [[OR]]:_(s32)
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 } // namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
index 42371e6..b342143 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
@@ -1,14 +1,14 @@
 //===- llvm/unittest/CodeGen/GlobalISel/LegalizerInfoTest.cpp -------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
 #include "llvm/CodeGen/TargetOpcodes.h"
+#include "GISelMITest.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -34,12 +34,9 @@
   return OS;
 }
 
-std::ostream &
-operator<<(std::ostream &OS, const llvm::LLT Ty) {
-  std::string Repr;
-  raw_string_ostream SS{Repr};
-  Ty.print(SS);
-  OS << SS.str();
+std::ostream &operator<<(std::ostream &OS, const llvm::LegalizeActionStep Ty) {
+  OS << "LegalizeActionStep(" << Ty.Action << ", " << Ty.TypeIdx << ", "
+     << Ty.NewType << ')';
   return OS;
 }
 }
@@ -62,28 +59,28 @@
 
   for (unsigned opcode : {G_ADD, G_SUB}) {
     // Check we infer the correct types and actually do what we're told.
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(8)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(8)}}),
               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(16)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(16)}}),
               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(32)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(32)}}),
               LegalizeActionStep(Legal, 0, LLT{}));
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(64)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(64)}}),
               LegalizeActionStep(Legal, 0, LLT{}));
 
     // Make sure the default for over-sized types applies.
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(128)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(128)}}),
               LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
     // Make sure we also handle unusual sizes
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(1)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(1)}}),
               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(31)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(31)}}),
               LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(33)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(33)}}),
               LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(63)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(63)}}),
               LegalizeActionStep(WidenScalar, 0, LLT::scalar(64)));
-    ASSERT_EQ(L.getAction({opcode, {LLT::scalar(65)}}),
+    EXPECT_EQ(L.getAction({opcode, {LLT::scalar(65)}}),
               LegalizeActionStep(NarrowScalar, 0, LLT::scalar(64)));
   }
 }
@@ -108,18 +105,18 @@
 
   // Check we infer the correct types and actually do what we're told for some
   // simple cases.
-  ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 8)}}),
+  EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(8, 8)}}),
             LegalizeActionStep(Legal, 0, LLT{}));
-  ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 7)}}),
+  EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(8, 7)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::vector(8, 8)));
-  ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(2, 8)}}),
+  EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(2, 8)}}),
             LegalizeActionStep(MoreElements, 0, LLT::vector(8, 8)));
-  ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(8, 32)}}),
+  EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(8, 32)}}),
             LegalizeActionStep(FewerElements, 0, LLT::vector(4, 32)));
   // Check a few non-power-of-2 sizes:
-  ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 3)}}),
+  EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(3, 3)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::vector(3, 8)));
-  ASSERT_EQ(L.getAction({G_ADD, {LLT::vector(3, 8)}}),
+  EXPECT_EQ(L.getAction({G_ADD, {LLT::vector(3, 8)}}),
             LegalizeActionStep(MoreElements, 0, LLT::vector(8, 8)));
 }
 
@@ -139,14 +136,14 @@
   L.computeTables();
 
   // Check we infer the correct types and actually do what we're told.
-  ASSERT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}),
+  EXPECT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}),
             LegalizeActionStep(Legal, 0, LLT{}));
 
   // Make sure we also handle unusual sizes
-  ASSERT_EQ(
+  EXPECT_EQ(
       L.getAction({G_PTRTOINT, {LLT::scalar(65), s64}}),
       LegalizeActionStep(NarrowScalar, 0, s64));
-  ASSERT_EQ(
+  EXPECT_EQ(
       L.getAction({G_PTRTOINT, {s64, LLT::pointer(0, 32)}}),
       LegalizeActionStep(Unsupported, 1, LLT::pointer(0, 32)));
 }
@@ -164,9 +161,9 @@
 
   L.computeTables();
 
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(32)}}),
             LegalizeActionStep(Lower, 0, LLT::scalar(32)));
 }
 
@@ -182,20 +179,229 @@
 
   // Check we infer the correct types and actually do what we're told.
   for (unsigned Size : {1, 8, 16, 32}) {
-    ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}),
+    EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(Size)}}),
               LegalizeActionStep(Legal, 0, LLT{}));
   }
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(2)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(7)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::scalar(8)));
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(9)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::scalar(16)));
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(17)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(31)}}),
             LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
-  ASSERT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}),
+  EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(33)}}),
             LegalizeActionStep(Unsupported, 0, LLT::scalar(33)));
 }
 }
+
+#define EXPECT_ACTION(Action, Index, Type, Query)                              \
+  do {                                                                         \
+    auto A = LI.getAction(Query);                                              \
+    EXPECT_EQ(LegalizeActionStep(Action, Index, Type), A) << A;                \
+  } while (0)
+
+TEST(LegalizerInfoTest, RuleSets) {
+  using namespace TargetOpcode;
+
+  const LLT s5 = LLT::scalar(5);
+  const LLT s8 = LLT::scalar(8);
+  const LLT s16 = LLT::scalar(16);
+  const LLT s32 = LLT::scalar(32);
+  const LLT s33 = LLT::scalar(33);
+  const LLT s64 = LLT::scalar(64);
+
+  const LLT v2s5 = LLT::vector(2, 5);
+  const LLT v2s8 = LLT::vector(2, 8);
+  const LLT v2s16 = LLT::vector(2, 16);
+  const LLT v2s32 = LLT::vector(2, 32);
+  const LLT v3s32 = LLT::vector(3, 32);
+  const LLT v4s32 = LLT::vector(4, 32);
+  const LLT v2s33 = LLT::vector(2, 33);
+  const LLT v2s64 = LLT::vector(2, 64);
+
+  const LLT p0 = LLT::pointer(0, 32);
+  const LLT v3p0 = LLT::vector(3, p0);
+  const LLT v4p0 = LLT::vector(4, p0);
+
+  {
+    LegalizerInfo LI;
+
+    LI.getActionDefinitionsBuilder(G_IMPLICIT_DEF)
+      .legalFor({v4s32, v4p0})
+      .moreElementsToNextPow2(0);
+    LI.computeTables();
+
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {s32}));
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {v2s32}));
+    EXPECT_ACTION(MoreElements, 0, v4p0, LegalityQuery(G_IMPLICIT_DEF, {v3p0}));
+    EXPECT_ACTION(MoreElements, 0, v4s32, LegalityQuery(G_IMPLICIT_DEF, {v3s32}));
+  }
+
+  // Test minScalarOrElt
+  {
+    LegalizerInfo LI;
+    LI.getActionDefinitionsBuilder(G_OR)
+      .legalFor({s32})
+      .minScalarOrElt(0, s32);
+    LI.computeTables();
+
+    EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
+    EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_OR, {v2s16}));
+  }
+
+  // Test maxScalarOrELt
+  {
+    LegalizerInfo LI;
+    LI.getActionDefinitionsBuilder(G_AND)
+      .legalFor({s16})
+      .maxScalarOrElt(0, s16);
+    LI.computeTables();
+
+    EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
+    EXPECT_ACTION(NarrowScalar, 0, v2s16, LegalityQuery(G_AND, {v2s32}));
+  }
+
+  // Test clampScalarOrElt
+  {
+    LegalizerInfo LI;
+    LI.getActionDefinitionsBuilder(G_XOR)
+      .legalFor({s16})
+      .clampScalarOrElt(0, s16, s32);
+    LI.computeTables();
+
+    EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
+    EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
+
+    // Make sure the number of elements is preserved.
+    EXPECT_ACTION(NarrowScalar, 0, v2s32, LegalityQuery(G_XOR, {v2s64}));
+    EXPECT_ACTION(WidenScalar, 0, v2s16, LegalityQuery(G_XOR, {v2s8}));
+  }
+
+  // Test minScalar
+  {
+    LegalizerInfo LI;
+    LI.getActionDefinitionsBuilder(G_OR)
+      .legalFor({s32})
+      .minScalar(0, s32);
+    LI.computeTables();
+
+    // Only handle scalars, ignore vectors.
+    EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_OR, {v2s16}));
+  }
+
+  // Test maxScalar
+  {
+    LegalizerInfo LI;
+    LI.getActionDefinitionsBuilder(G_AND)
+      .legalFor({s16})
+      .maxScalar(0, s16);
+    LI.computeTables();
+
+    // Only handle scalars, ignore vectors.
+    EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s32}));
+  }
+
+  // Test clampScalar
+  {
+    LegalizerInfo LI;
+
+    LI.getActionDefinitionsBuilder(G_XOR)
+      .legalFor({s16})
+      .clampScalar(0, s16, s32);
+    LI.computeTables();
+
+    EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
+    EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
+
+    // Only handle scalars, ignore vectors.
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s64}));
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_XOR, {v2s8}));
+  }
+
+  // Test widenScalarOrEltToNextPow2
+  {
+    LegalizerInfo LI;
+
+    LI.getActionDefinitionsBuilder(G_AND)
+      .legalFor({s32})
+      .widenScalarOrEltToNextPow2(0, 32);
+    LI.computeTables();
+
+    // Handle scalars and vectors
+    EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
+    EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_AND, {v2s5}));
+    EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33}));
+    EXPECT_ACTION(WidenScalar, 0, v2s64, LegalityQuery(G_AND, {v2s33}));
+  }
+
+  // Test widenScalarToNextPow2
+  {
+    LegalizerInfo LI;
+
+    LI.getActionDefinitionsBuilder(G_AND)
+      .legalFor({s32})
+      .widenScalarToNextPow2(0, 32);
+    LI.computeTables();
+
+    EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
+    EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33}));
+
+    // Do nothing for vectors.
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s5}));
+    EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_AND, {v2s33}));
+  }
+}
+
+TEST(LegalizerInfoTest, MMOAlignment) {
+  using namespace TargetOpcode;
+
+  const LLT s32 = LLT::scalar(32);
+  const LLT p0 = LLT::pointer(0, 64);
+
+  {
+    LegalizerInfo LI;
+    LI.getActionDefinitionsBuilder(G_LOAD)
+      .legalForTypesWithMemDesc({{s32, p0, 32, 32}});
+
+    LI.computeTables();
+
+    EXPECT_ACTION(Legal, 0, LLT(),
+                  LegalityQuery(G_LOAD, {s32, p0},
+                                LegalityQuery::MemDesc{
+                                  32, 32, AtomicOrdering::NotAtomic}));
+    EXPECT_ACTION(Unsupported, 0, LLT(),
+                  LegalityQuery(G_LOAD, {s32, p0},
+                                LegalityQuery::MemDesc{
+                                  32, 16, AtomicOrdering::NotAtomic }));
+    EXPECT_ACTION(Unsupported, 0, LLT(),
+                  LegalityQuery(G_LOAD, {s32, p0},
+                                LegalityQuery::MemDesc{
+                                  32, 8, AtomicOrdering::NotAtomic}));
+  }
+
+  // Test that the maximum supported alignment value isn't truncated
+  {
+    // Maximum IR defined alignment in bytes.
+    const uint64_t MaxAlignment = UINT64_C(1) << 29;
+    const uint64_t MaxAlignInBits = 8 * MaxAlignment;
+    LegalizerInfo LI;
+    LI.getActionDefinitionsBuilder(G_LOAD)
+      .legalForTypesWithMemDesc({{s32, p0, 32, MaxAlignInBits}});
+
+    LI.computeTables();
+
+    EXPECT_ACTION(Legal, 0, LLT(),
+                  LegalityQuery(G_LOAD, {s32, p0},
+                                LegalityQuery::MemDesc{32,
+                                    MaxAlignInBits, AtomicOrdering::NotAtomic}));
+    EXPECT_ACTION(Unsupported, 0, LLT(),
+                  LegalityQuery(G_LOAD, {s32, p0},
+                                LegalityQuery::MemDesc{
+                                  32, 8, AtomicOrdering::NotAtomic }));
+  }
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
new file mode 100644
index 0000000..f6d8112
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp
@@ -0,0 +1,280 @@
+//===- MachineIRBuilderTest.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "GISelMITest.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+
+TEST_F(GISelMITest, TestBuildConstantFConstant) {
+  if (!TM)
+    return;
+
+  B.buildConstant(LLT::scalar(32), 42);
+  B.buildFConstant(LLT::scalar(32), 1.0);
+
+  B.buildConstant(LLT::vector(2, 32), 99);
+  B.buildFConstant(LLT::vector(2, 32), 2.0);
+
+  // Test APFloat overload.
+  APFloat KVal(APFloat::IEEEdouble(), "4.0");
+  B.buildFConstant(LLT::scalar(64), KVal);
+
+  auto CheckStr = R"(
+  CHECK: [[CONST0:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
+  CHECK: [[FCONST0:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00
+  CHECK: [[CONST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 99
+  CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[CONST1]]:_(s32), [[CONST1]]:_(s32)
+  CHECK: [[FCONST1:%[0-9]+]]:_(s32) = G_FCONSTANT float 2.000000e+00
+  CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FCONST1]]:_(s32), [[FCONST1]]:_(s32)
+  CHECK: [[FCONST2:%[0-9]+]]:_(s64) = G_FCONSTANT double 4.000000e+00
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+
+TEST_F(GISelMITest, TestBuildConstantFConstantDeath) {
+  if (!TM)
+    return;
+
+  LLVMContext &Ctx = MF->getFunction().getContext();
+  APInt APV32(32, 12345);
+
+  // Test APInt version breaks
+  EXPECT_DEATH(B.buildConstant(LLT::scalar(16), APV32),
+               "creating constant with the wrong size");
+  EXPECT_DEATH(B.buildConstant(LLT::vector(2, 16), APV32),
+               "creating constant with the wrong size");
+
+  // Test ConstantInt version breaks
+  ConstantInt *CI = ConstantInt::get(Ctx, APV32);
+  EXPECT_DEATH(B.buildConstant(LLT::scalar(16), *CI),
+               "creating constant with the wrong size");
+  EXPECT_DEATH(B.buildConstant(LLT::vector(2, 16), *CI),
+               "creating constant with the wrong size");
+
+  APFloat DoubleVal(APFloat::IEEEdouble());
+  ConstantFP *CF = ConstantFP::get(Ctx, DoubleVal);
+  EXPECT_DEATH(B.buildFConstant(LLT::scalar(16), *CF),
+               "creating fconstant with the wrong size");
+  EXPECT_DEATH(B.buildFConstant(LLT::vector(2, 16), *CF),
+               "creating fconstant with the wrong size");
+}
+
+#endif
+#endif
+
+TEST_F(GISelMITest, DstOpSrcOp) {
+  if (!TM)
+    return;
+
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+
+  LLT s64 = LLT::scalar(64);
+  auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
+
+  // Test SrcOp and DstOp can be constructed directly from MachineOperand by
+  // copying the instruction
+  B.buildAdd(MIBAdd->getOperand(0), MIBAdd->getOperand(1), MIBAdd->getOperand(2));
+
+
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+  ; CHECK: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY0]]:_, [[COPY1]]:_
+  ; CHECK: [[ADD]]:_(s64) = G_ADD [[COPY0]]:_, [[COPY1]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildUnmerge) {
+  if (!TM)
+    return;
+
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+  B.buildUnmerge(LLT::scalar(32), Copies[0]);
+  B.buildUnmerge(LLT::scalar(16), Copies[1]);
+
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+  ; CHECK: [[UNMERGE32_0:%[0-9]+]]:_(s32), [[UNMERGE32_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY0]]
+  ; CHECK: [[UNMERGE16_0:%[0-9]+]]:_(s16), [[UNMERGE16_1:%[0-9]+]]:_(s16), [[UNMERGE16_2:%[0-9]+]]:_(s16), [[UNMERGE16_3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[COPY1]]
+
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, TestBuildFPInsts) {
+  if (!TM)
+    return;
+
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+
+  LLT S64 = LLT::scalar(64);
+
+  B.buildFAdd(S64, Copies[0], Copies[1]);
+  B.buildFSub(S64, Copies[0], Copies[1]);
+  B.buildFMA(S64, Copies[0], Copies[1], Copies[2]);
+  B.buildFNeg(S64, Copies[0]);
+  B.buildFAbs(S64, Copies[0]);
+  B.buildFCopysign(S64, Copies[0], Copies[1]);
+
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+  ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2
+  ; CHECK: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[COPY0]]:_, [[COPY1]]:_
+  ; CHECK: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[COPY0]]:_, [[COPY1]]:_
+  ; CHECK: [[FMA:%[0-9]+]]:_(s64) = G_FMA [[COPY0]]:_, [[COPY1]]:_, [[COPY2]]:_
+  ; CHECK: [[FNEG:%[0-9]+]]:_(s64) = G_FNEG [[COPY0]]:_
+  ; CHECK: [[FABS:%[0-9]+]]:_(s64) = G_FABS [[COPY0]]:_
+  ; CHECK: [[FCOPYSIGN:%[0-9]+]]:_(s64) = G_FCOPYSIGN [[COPY0]]:_, [[COPY1]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildIntrinsic) {
+  if (!TM)
+    return;
+
+  LLT S64 = LLT::scalar(64);
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+
+  // Make sure DstOp version works. sqrt is just a placeholder intrinsic.
+  B.buildIntrinsic(Intrinsic::sqrt, {S64}, false)
+    .addUse(Copies[0]);
+
+  // Make sure register version works
+  SmallVector<Register, 1> Results;
+  Results.push_back(MRI->createGenericVirtualRegister(S64));
+  B.buildIntrinsic(Intrinsic::sqrt, Results, false)
+    .addUse(Copies[1]);
+
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+  ; CHECK: [[SQRT0:%[0-9]+]]:_(s64) = G_INTRINSIC intrinsic(@llvm.sqrt), [[COPY0]]:_
+  ; CHECK: [[SQRT1:%[0-9]+]]:_(s64) = G_INTRINSIC intrinsic(@llvm.sqrt), [[COPY1]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildXor) {
+  if (!TM)
+    return;
+
+  LLT S64 = LLT::scalar(64);
+  LLT S128 = LLT::scalar(128);
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+  B.buildXor(S64, Copies[0], Copies[1]);
+  B.buildNot(S64, Copies[0]);
+
+  // Make sure this works with > 64-bit types
+  auto Merge = B.buildMerge(S128, {Copies[0], Copies[1]});
+  B.buildNot(S128, Merge);
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+  ; CHECK: [[XOR0:%[0-9]+]]:_(s64) = G_XOR [[COPY0]]:_, [[COPY1]]:_
+  ; CHECK: [[NEGONE64:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+  ; CHECK: [[XOR1:%[0-9]+]]:_(s64) = G_XOR [[COPY0]]:_, [[NEGONE64]]:_
+  ; CHECK: [[MERGE:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[COPY0]]:_(s64), [[COPY1]]:_(s64)
+  ; CHECK: [[NEGONE128:%[0-9]+]]:_(s128) = G_CONSTANT i128 -1
+  ; CHECK: [[XOR2:%[0-9]+]]:_(s128) = G_XOR [[MERGE]]:_, [[NEGONE128]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildBitCounts) {
+  if (!TM)
+    return;
+
+  LLT S32 = LLT::scalar(32);
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+
+  B.buildCTPOP(S32, Copies[0]);
+  B.buildCTLZ(S32, Copies[0]);
+  B.buildCTLZ_ZERO_UNDEF(S32, Copies[1]);
+  B.buildCTTZ(S32, Copies[0]);
+  B.buildCTTZ_ZERO_UNDEF(S32, Copies[1]);
+
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+  ; CHECK: [[CTPOP:%[0-9]+]]:_(s32) = G_CTPOP [[COPY0]]:_
+  ; CHECK: [[CTLZ0:%[0-9]+]]:_(s32) = G_CTLZ [[COPY0]]:_
+  ; CHECK: [[CTLZ_UNDEF0:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[COPY1]]:_
+  ; CHECK: [[CTTZ:%[0-9]+]]:_(s32) = G_CTTZ [[COPY0]]:_
+  ; CHECK: [[CTTZ_UNDEF0:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[COPY1]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildCasts) {
+  if (!TM)
+    return;
+
+  LLT S32 = LLT::scalar(32);
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+
+  B.buildUITOFP(S32, Copies[0]);
+  B.buildSITOFP(S32, Copies[0]);
+  B.buildFPTOUI(S32, Copies[0]);
+  B.buildFPTOSI(S32, Copies[0]);
+
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[UITOFP:%[0-9]+]]:_(s32) = G_UITOFP [[COPY0]]:_
+  ; CHECK: [[SITOFP:%[0-9]+]]:_(s32) = G_SITOFP [[COPY0]]:_
+  ; CHECK: [[FPTOUI:%[0-9]+]]:_(s32) = G_FPTOUI [[COPY0]]:_
+  ; CHECK: [[FPTOSI:%[0-9]+]]:_(s32) = G_FPTOSI [[COPY0]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(GISelMITest, BuildMinMax) {
+  if (!TM)
+    return;
+
+  LLT S64 = LLT::scalar(64);
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+
+  B.buildSMin(S64, Copies[0], Copies[1]);
+  B.buildSMax(S64, Copies[0], Copies[1]);
+  B.buildUMin(S64, Copies[0], Copies[1]);
+  B.buildUMax(S64, Copies[0], Copies[1]);
+
+  auto CheckStr = R"(
+  ; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
+  ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+  ; CHECK: [[SMIN0:%[0-9]+]]:_(s64) = G_SMIN [[COPY0]]:_, [[COPY1]]:_
+  ; CHECK: [[SMAX0:%[0-9]+]]:_(s64) = G_SMAX [[COPY0]]:_, [[COPY1]]:_
+  ; CHECK: [[UMIN0:%[0-9]+]]:_(s64) = G_UMIN [[COPY0]]:_, [[COPY1]]:_
+  ; CHECK: [[UMAX0:%[0-9]+]]:_(s64) = G_UMAX [[COPY0]]:_, [[COPY1]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
index 466a2dd..7ba7918 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp
@@ -1,9 +1,8 @@
 //===- PatternMatchTest.cpp -----------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -112,7 +111,7 @@
   return MF;
 }
 
-static void collectCopies(SmallVectorImpl<unsigned> &Copies,
+static void collectCopies(SmallVectorImpl<Register> &Copies,
                           MachineFunction *MF) {
   for (auto &MBB : *MF)
     for (MachineInstr &MI : MBB) {
@@ -129,7 +128,7 @@
   auto ModuleMMIPair = createDummyModule(Context, *TM, "");
   MachineFunction *MF =
       getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
-  SmallVector<unsigned, 4> Copies;
+  SmallVector<Register, 4> Copies;
   collectCopies(Copies, MF);
   MachineBasicBlock *EntryMBB = &*MF->begin();
   MachineIRBuilder B(*MF);
@@ -138,8 +137,8 @@
   auto MIBCst = B.buildConstant(LLT::scalar(64), 42);
   int64_t Cst;
   bool match = mi_match(MIBCst->getOperand(0).getReg(), MRI, m_ICst(Cst));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Cst, 42);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Cst, 42);
 }
 
 TEST(PatternMatchInstr, MatchBinaryOp) {
@@ -150,7 +149,7 @@
   auto ModuleMMIPair = createDummyModule(Context, *TM, "");
   MachineFunction *MF =
       getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
-  SmallVector<unsigned, 4> Copies;
+  SmallVector<Register, 4> Copies;
   collectCopies(Copies, MF);
   MachineBasicBlock *EntryMBB = &*MF->begin();
   MachineIRBuilder B(*MF);
@@ -161,13 +160,13 @@
   // Test case for no bind.
   bool match =
       mi_match(MIBAdd->getOperand(0).getReg(), MRI, m_GAdd(m_Reg(), m_Reg()));
-  ASSERT_TRUE(match);
-  unsigned Src0, Src1, Src2;
+  EXPECT_TRUE(match);
+  Register Src0, Src1, Src2;
   match = mi_match(MIBAdd->getOperand(0).getReg(), MRI,
                    m_GAdd(m_Reg(Src0), m_Reg(Src1)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
-  ASSERT_EQ(Src1, Copies[1]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
+  EXPECT_EQ(Src1, Copies[1]);
 
   // Build MUL(ADD %0, %1), %2
   auto MIBMul = B.buildMul(s64, MIBAdd, Copies[2]);
@@ -175,17 +174,17 @@
   // Try to match MUL.
   match = mi_match(MIBMul->getOperand(0).getReg(), MRI,
                    m_GMul(m_Reg(Src0), m_Reg(Src1)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, MIBAdd->getOperand(0).getReg());
-  ASSERT_EQ(Src1, Copies[2]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, MIBAdd->getOperand(0).getReg());
+  EXPECT_EQ(Src1, Copies[2]);
 
   // Try to match MUL(ADD)
   match = mi_match(MIBMul->getOperand(0).getReg(), MRI,
                    m_GMul(m_GAdd(m_Reg(Src0), m_Reg(Src1)), m_Reg(Src2)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
-  ASSERT_EQ(Src1, Copies[1]);
-  ASSERT_EQ(Src2, Copies[2]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
+  EXPECT_EQ(Src1, Copies[1]);
+  EXPECT_EQ(Src2, Copies[2]);
 
   // Test Commutativity.
   auto MIBMul2 = B.buildMul(s64, Copies[0], B.buildConstant(s64, 42));
@@ -194,50 +193,50 @@
   int64_t Cst;
   match = mi_match(MIBMul2->getOperand(0).getReg(), MRI,
                    m_GMul(m_ICst(Cst), m_Reg(Src0)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Cst, 42);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Cst, 42);
+  EXPECT_EQ(Src0, Copies[0]);
 
   // Make sure commutative doesn't work with something like SUB.
   auto MIBSub = B.buildSub(s64, Copies[0], B.buildConstant(s64, 42));
   match = mi_match(MIBSub->getOperand(0).getReg(), MRI,
                    m_GSub(m_ICst(Cst), m_Reg(Src0)));
-  ASSERT_FALSE(match);
+  EXPECT_FALSE(match);
 
   auto MIBFMul = B.buildInstr(TargetOpcode::G_FMUL, {s64},
                               {Copies[0], B.buildConstant(s64, 42)});
   // Match and test commutativity for FMUL.
   match = mi_match(MIBFMul->getOperand(0).getReg(), MRI,
                    m_GFMul(m_ICst(Cst), m_Reg(Src0)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Cst, 42);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Cst, 42);
+  EXPECT_EQ(Src0, Copies[0]);
 
   // FSUB
   auto MIBFSub = B.buildInstr(TargetOpcode::G_FSUB, {s64},
                               {Copies[0], B.buildConstant(s64, 42)});
   match = mi_match(MIBFSub->getOperand(0).getReg(), MRI,
                    m_GFSub(m_Reg(Src0), m_Reg()));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
 
   // Build AND %0, %1
   auto MIBAnd = B.buildAnd(s64, Copies[0], Copies[1]);
   // Try to match AND.
   match = mi_match(MIBAnd->getOperand(0).getReg(), MRI,
                    m_GAnd(m_Reg(Src0), m_Reg(Src1)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
-  ASSERT_EQ(Src1, Copies[1]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
+  EXPECT_EQ(Src1, Copies[1]);
 
   // Build OR %0, %1
   auto MIBOr = B.buildOr(s64, Copies[0], Copies[1]);
   // Try to match OR.
   match = mi_match(MIBOr->getOperand(0).getReg(), MRI,
                    m_GOr(m_Reg(Src0), m_Reg(Src1)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
-  ASSERT_EQ(Src1, Copies[1]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
+  EXPECT_EQ(Src1, Copies[1]);
 
   // Try to use the FoldableInstructionsBuilder to build binary ops.
   ConstantFoldingMIRBuilder CFB(B.getState());
@@ -246,15 +245,15 @@
       CFB.buildAdd(s32, CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1));
   // This should be a constant now.
   match = mi_match(MIBCAdd->getOperand(0).getReg(), MRI, m_ICst(Cst));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Cst, 1);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Cst, 1);
   auto MIBCAdd1 =
       CFB.buildInstr(TargetOpcode::G_ADD, {s32},
                      {CFB.buildConstant(s32, 0), CFB.buildConstant(s32, 1)});
   // This should be a constant now.
   match = mi_match(MIBCAdd1->getOperand(0).getReg(), MRI, m_ICst(Cst));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Cst, 1);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Cst, 1);
 
   // Try one of the other constructors of MachineIRBuilder to make sure it's
   // compatible.
@@ -265,8 +264,8 @@
                       {CFB1.buildConstant(s32, 1), CFB1.buildConstant(s32, 1)});
   // This should be a constant now.
   match = mi_match(MIBCSub->getOperand(0).getReg(), MRI, m_ICst(Cst));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Cst, 0);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Cst, 0);
 }
 
 TEST(PatternMatchInstr, MatchFPUnaryOp) {
@@ -277,7 +276,7 @@
   auto ModuleMMIPair = createDummyModule(Context, *TM, "");
   MachineFunction *MF =
       getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
-  SmallVector<unsigned, 4> Copies;
+  SmallVector<Register, 4> Copies;
   collectCopies(Copies, MF);
   MachineBasicBlock *EntryMBB = &*MF->begin();
   MachineIRBuilder B(*MF);
@@ -291,53 +290,53 @@
   // Match G_FABS.
   auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, {s32}, {Copy0s32});
   bool match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg()));
-  ASSERT_TRUE(match);
+  EXPECT_TRUE(match);
 
-  unsigned Src;
+  Register Src;
   auto MIBFNeg = B.buildInstr(TargetOpcode::G_FNEG, {s32}, {Copy0s32});
   match = mi_match(MIBFNeg->getOperand(0).getReg(), MRI, m_GFNeg(m_Reg(Src)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src, Copy0s32->getOperand(0).getReg());
 
   match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg(Src)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src, Copy0s32->getOperand(0).getReg());
 
   // Build and match FConstant.
   auto MIBFCst = B.buildFConstant(s32, .5);
   const ConstantFP *TmpFP{};
   match = mi_match(MIBFCst->getOperand(0).getReg(), MRI, m_GFCst(TmpFP));
-  ASSERT_TRUE(match);
-  ASSERT_TRUE(TmpFP);
+  EXPECT_TRUE(match);
+  EXPECT_TRUE(TmpFP);
   APFloat APF((float).5);
   auto *CFP = ConstantFP::get(Context, APF);
-  ASSERT_EQ(CFP, TmpFP);
+  EXPECT_EQ(CFP, TmpFP);
 
   // Build double float.
   LLT s64 = LLT::scalar(64);
   auto MIBFCst64 = B.buildFConstant(s64, .5);
   const ConstantFP *TmpFP64{};
   match = mi_match(MIBFCst64->getOperand(0).getReg(), MRI, m_GFCst(TmpFP64));
-  ASSERT_TRUE(match);
-  ASSERT_TRUE(TmpFP64);
+  EXPECT_TRUE(match);
+  EXPECT_TRUE(TmpFP64);
   APFloat APF64(.5);
   auto CFP64 = ConstantFP::get(Context, APF64);
-  ASSERT_EQ(CFP64, TmpFP64);
-  ASSERT_NE(TmpFP64, TmpFP);
+  EXPECT_EQ(CFP64, TmpFP64);
+  EXPECT_NE(TmpFP64, TmpFP);
 
   // Build half float.
   LLT s16 = LLT::scalar(16);
   auto MIBFCst16 = B.buildFConstant(s16, .5);
   const ConstantFP *TmpFP16{};
   match = mi_match(MIBFCst16->getOperand(0).getReg(), MRI, m_GFCst(TmpFP16));
-  ASSERT_TRUE(match);
-  ASSERT_TRUE(TmpFP16);
+  EXPECT_TRUE(match);
+  EXPECT_TRUE(TmpFP16);
   bool Ignored;
   APFloat APF16(.5);
   APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
   auto CFP16 = ConstantFP::get(Context, APF16);
-  ASSERT_EQ(TmpFP16, CFP16);
-  ASSERT_NE(TmpFP16, TmpFP);
+  EXPECT_EQ(TmpFP16, CFP16);
+  EXPECT_NE(TmpFP16, TmpFP);
 }
 
 TEST(PatternMatchInstr, MatchExtendsTrunc) {
@@ -348,7 +347,7 @@
   auto ModuleMMIPair = createDummyModule(Context, *TM, "");
   MachineFunction *MF =
       getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
-  SmallVector<unsigned, 4> Copies;
+  SmallVector<Register, 4> Copies;
   collectCopies(Copies, MF);
   MachineBasicBlock *EntryMBB = &*MF->begin();
   MachineIRBuilder B(*MF);
@@ -361,39 +360,39 @@
   auto MIBAExt = B.buildAnyExt(s64, MIBTrunc);
   auto MIBZExt = B.buildZExt(s64, MIBTrunc);
   auto MIBSExt = B.buildSExt(s64, MIBTrunc);
-  unsigned Src0;
+  Register Src0;
   bool match =
       mi_match(MIBTrunc->getOperand(0).getReg(), MRI, m_GTrunc(m_Reg(Src0)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
   match =
       mi_match(MIBAExt->getOperand(0).getReg(), MRI, m_GAnyExt(m_Reg(Src0)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
 
   match = mi_match(MIBSExt->getOperand(0).getReg(), MRI, m_GSExt(m_Reg(Src0)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
 
   match = mi_match(MIBZExt->getOperand(0).getReg(), MRI, m_GZExt(m_Reg(Src0)));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, MIBTrunc->getOperand(0).getReg());
 
   // Match ext(trunc src)
   match = mi_match(MIBAExt->getOperand(0).getReg(), MRI,
                    m_GAnyExt(m_GTrunc(m_Reg(Src0))));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
 
   match = mi_match(MIBSExt->getOperand(0).getReg(), MRI,
                    m_GSExt(m_GTrunc(m_Reg(Src0))));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
 
   match = mi_match(MIBZExt->getOperand(0).getReg(), MRI,
                    m_GZExt(m_GTrunc(m_Reg(Src0))));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
 }
 
 TEST(PatternMatchInstr, MatchSpecificType) {
@@ -404,7 +403,7 @@
   auto ModuleMMIPair = createDummyModule(Context, *TM, "");
   MachineFunction *MF =
       getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
-  SmallVector<unsigned, 4> Copies;
+  SmallVector<Register, 4> Copies;
   collectCopies(Copies, MF);
   MachineBasicBlock *EntryMBB = &*MF->begin();
   MachineIRBuilder B(*MF);
@@ -415,32 +414,32 @@
   LLT s64 = LLT::scalar(64);
   LLT s32 = LLT::scalar(32);
   auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
-  ASSERT_FALSE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
+  EXPECT_FALSE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
                         m_GAdd(m_SpecificType(s32), m_Reg())));
-  ASSERT_TRUE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
+  EXPECT_TRUE(mi_match(MIBAdd->getOperand(0).getReg(), MRI,
                        m_GAdd(m_SpecificType(s64), m_Reg())));
 
   // Try to match the destination type of a bitcast.
   LLT v2s32 = LLT::vector(2, 32);
   auto MIBCast = B.buildCast(v2s32, Copies[0]);
-  ASSERT_TRUE(
+  EXPECT_TRUE(
       mi_match(MIBCast->getOperand(0).getReg(), MRI, m_GBitcast(m_Reg())));
-  ASSERT_TRUE(
+  EXPECT_TRUE(
       mi_match(MIBCast->getOperand(0).getReg(), MRI, m_SpecificType(v2s32)));
-  ASSERT_TRUE(
+  EXPECT_TRUE(
       mi_match(MIBCast->getOperand(1).getReg(), MRI, m_SpecificType(s64)));
 
   // Build a PTRToInt and INTTOPTR and match and test them.
   LLT PtrTy = LLT::pointer(0, 64);
   auto MIBIntToPtr = B.buildCast(PtrTy, Copies[0]);
   auto MIBPtrToInt = B.buildCast(s64, MIBIntToPtr);
-  unsigned Src0;
+  Register Src0;
 
   // match the ptrtoint(inttoptr reg)
   bool match = mi_match(MIBPtrToInt->getOperand(0).getReg(), MRI,
                         m_GPtrToInt(m_GIntToPtr(m_Reg(Src0))));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
 }
 
 TEST(PatternMatchInstr, MatchCombinators) {
@@ -451,7 +450,7 @@
   auto ModuleMMIPair = createDummyModule(Context, *TM, "");
   MachineFunction *MF =
       getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
-  SmallVector<unsigned, 4> Copies;
+  SmallVector<Register, 4> Copies;
   collectCopies(Copies, MF);
   MachineBasicBlock *EntryMBB = &*MF->begin();
   MachineIRBuilder B(*MF);
@@ -460,30 +459,55 @@
   LLT s64 = LLT::scalar(64);
   LLT s32 = LLT::scalar(32);
   auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
-  unsigned Src0, Src1;
+  Register Src0, Src1;
   bool match =
       mi_match(MIBAdd->getOperand(0).getReg(), MRI,
                m_all_of(m_SpecificType(s64), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
-  ASSERT_EQ(Src1, Copies[1]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
+  EXPECT_EQ(Src1, Copies[1]);
   // Check for s32 (which should fail).
   match =
       mi_match(MIBAdd->getOperand(0).getReg(), MRI,
                m_all_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
-  ASSERT_FALSE(match);
+  EXPECT_FALSE(match);
   match =
       mi_match(MIBAdd->getOperand(0).getReg(), MRI,
                m_any_of(m_SpecificType(s32), m_GAdd(m_Reg(Src0), m_Reg(Src1))));
-  ASSERT_TRUE(match);
-  ASSERT_EQ(Src0, Copies[0]);
-  ASSERT_EQ(Src1, Copies[1]);
+  EXPECT_TRUE(match);
+  EXPECT_EQ(Src0, Copies[0]);
+  EXPECT_EQ(Src1, Copies[1]);
 
   // Match a case where none of the predicates hold true.
   match = mi_match(
       MIBAdd->getOperand(0).getReg(), MRI,
       m_any_of(m_SpecificType(LLT::scalar(16)), m_GSub(m_Reg(), m_Reg())));
-  ASSERT_FALSE(match);
+  EXPECT_FALSE(match);
+}
+
+TEST(PatternMatchInstr, MatchMiscellaneous) {
+  LLVMContext Context;
+  std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
+  if (!TM)
+    return;
+  auto ModuleMMIPair = createDummyModule(Context, *TM, "");
+  MachineFunction *MF =
+      getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
+  SmallVector<Register, 4> Copies;
+  collectCopies(Copies, MF);
+  MachineBasicBlock *EntryMBB = &*MF->begin();
+  MachineIRBuilder B(*MF);
+  MachineRegisterInfo &MRI = MF->getRegInfo();
+  B.setInsertPt(*EntryMBB, EntryMBB->end());
+  LLT s64 = LLT::scalar(64);
+  auto MIBAdd = B.buildAdd(s64, Copies[0], Copies[1]);
+  // Make multiple uses of this add.
+  B.buildCast(LLT::pointer(0, 32), MIBAdd);
+  B.buildCast(LLT::pointer(1, 32), MIBAdd);
+  bool match = mi_match(MIBAdd.getReg(0), MRI, m_GAdd(m_Reg(), m_Reg()));
+  EXPECT_TRUE(match);
+  match = mi_match(MIBAdd.getReg(0), MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())));
+  EXPECT_FALSE(match);
 }
 } // namespace
 
diff --git a/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
index a4765d9..bf4277d 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/CodeGen/GlobalISel/LowLevelTypeTest.cpp --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -16,18 +15,6 @@
 
 using namespace llvm;
 
-// Define a pretty printer to help debugging when things go wrong.
-namespace llvm {
-std::ostream &
-operator<<(std::ostream &OS, const llvm::LLT Ty) {
-  std::string Repr;
-  raw_string_ostream SS{Repr};
-  Ty.print(SS);
-  OS << SS.str();
-  return OS;
-}
-}
-
 namespace {
 
 TEST(LowLevelTypeTest, Scalar) {
@@ -104,41 +91,118 @@
   }
 }
 
+TEST(LowLevelTypeTest, ScalarOrVector) {
+  // Test version with number of bits for scalar type.
+  EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, 32));
+  EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, 32));
+
+  // Test version with LLT for scalar type.
+  EXPECT_EQ(LLT::scalar(32), LLT::scalarOrVector(1, LLT::scalar(32)));
+  EXPECT_EQ(LLT::vector(2, 32), LLT::scalarOrVector(2, LLT::scalar(32)));
+
+  // Test with pointer elements.
+  EXPECT_EQ(LLT::pointer(1, 32), LLT::scalarOrVector(1, LLT::pointer(1, 32)));
+  EXPECT_EQ(LLT::vector(2, LLT::pointer(1, 32)),
+            LLT::scalarOrVector(2, LLT::pointer(1, 32)));
+}
+
+TEST(LowLevelTypeTest, ChangeElementType) {
+  const LLT P0 = LLT::pointer(0, 32);
+  const LLT P1 = LLT::pointer(1, 64);
+
+  const LLT S32 = LLT::scalar(32);
+  const LLT S64 = LLT::scalar(64);
+
+  const LLT V2S32 = LLT::vector(2, 32);
+  const LLT V2S64 = LLT::vector(2, 64);
+
+  const LLT V2P0 = LLT::vector(2, P0);
+  const LLT V2P1 = LLT::vector(2, P1);
+
+  EXPECT_EQ(S64, S32.changeElementType(S64));
+  EXPECT_EQ(S32, S32.changeElementType(S32));
+
+  EXPECT_EQ(S32, S64.changeElementSize(32));
+  EXPECT_EQ(S32, S32.changeElementSize(32));
+
+  EXPECT_EQ(V2S64, V2S32.changeElementType(S64));
+  EXPECT_EQ(V2S32, V2S64.changeElementType(S32));
+
+  EXPECT_EQ(V2S64, V2S32.changeElementSize(64));
+  EXPECT_EQ(V2S32, V2S64.changeElementSize(32));
+
+  EXPECT_EQ(P0, S32.changeElementType(P0));
+  EXPECT_EQ(S32, P0.changeElementType(S32));
+
+  EXPECT_EQ(V2P1, V2P0.changeElementType(P1));
+  EXPECT_EQ(V2S32, V2P0.changeElementType(S32));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+
+// Invalid to directly change the element size for pointers.
+TEST(LowLevelTypeTest, ChangeElementTypeDeath) {
+  const LLT P0 = LLT::pointer(0, 32);
+  const LLT V2P0 = LLT::vector(2, P0);
+
+  EXPECT_DEATH(P0.changeElementSize(64),
+               "invalid to directly change element size for pointers");
+  EXPECT_DEATH(V2P0.changeElementSize(64),
+               "invalid to directly change element size for pointers");
+
+  // Make sure this still fails even without a change in size.
+  EXPECT_DEATH(P0.changeElementSize(32),
+               "invalid to directly change element size for pointers");
+  EXPECT_DEATH(V2P0.changeElementSize(32),
+               "invalid to directly change element size for pointers");
+}
+
+#endif
+#endif
+
 TEST(LowLevelTypeTest, Pointer) {
   LLVMContext C;
-  DataLayout DL("");
+  DataLayout DL("p64:64:64-p127:512:512:512-p16777215:65528:8");
 
-  for (unsigned AS : {0U, 1U, 127U, 0xffffU}) {
-    const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
-    const LLT VTy = LLT::vector(4, Ty);
+  for (unsigned AS : {0U, 1U, 127U, 0xffffU,
+        static_cast<unsigned>(maxUIntN(23)),
+        static_cast<unsigned>(maxUIntN(24))}) {
+    for (unsigned NumElts : {2, 3, 4, 256, 65535}) {
+      const LLT Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
+      const LLT VTy = LLT::vector(NumElts, Ty);
 
-    // Test kind.
-    ASSERT_TRUE(Ty.isValid());
-    ASSERT_TRUE(Ty.isPointer());
+      // Test kind.
+      ASSERT_TRUE(Ty.isValid());
+      ASSERT_TRUE(Ty.isPointer());
 
-    ASSERT_FALSE(Ty.isScalar());
-    ASSERT_FALSE(Ty.isVector());
+      ASSERT_FALSE(Ty.isScalar());
+      ASSERT_FALSE(Ty.isVector());
 
-    ASSERT_TRUE(VTy.isValid());
-    ASSERT_TRUE(VTy.isVector());
-    ASSERT_TRUE(VTy.getElementType().isPointer());
+      ASSERT_TRUE(VTy.isValid());
+      ASSERT_TRUE(VTy.isVector());
+      ASSERT_TRUE(VTy.getElementType().isPointer());
 
-    // Test addressspace.
-    EXPECT_EQ(AS, Ty.getAddressSpace());
-    EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
+      EXPECT_EQ(Ty, VTy.getElementType());
+      EXPECT_EQ(Ty.getSizeInBits(), VTy.getScalarSizeInBits());
 
-    // Test equality operators.
-    EXPECT_TRUE(Ty == Ty);
-    EXPECT_FALSE(Ty != Ty);
-    EXPECT_TRUE(VTy == VTy);
-    EXPECT_FALSE(VTy != VTy);
+      // Test address space.
+      EXPECT_EQ(AS, Ty.getAddressSpace());
+      EXPECT_EQ(AS, VTy.getElementType().getAddressSpace());
 
-    // Test Type->LLT conversion.
-    Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
-    EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
-    Type *IRVTy =
-        VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), 4);
-    EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
+      // Test equality operators.
+      EXPECT_TRUE(Ty == Ty);
+      EXPECT_FALSE(Ty != Ty);
+      EXPECT_TRUE(VTy == VTy);
+      EXPECT_FALSE(VTy != VTy);
+
+      // Test Type->LLT conversion.
+      Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS);
+      EXPECT_EQ(Ty, getLLTForType(*IRTy, DL));
+      Type *IRVTy =
+        VectorType::get(PointerType::get(IntegerType::get(C, 8), AS), NumElts);
+      EXPECT_EQ(VTy, getLLTForType(*IRVTy, DL));
+    }
   }
 }
 
diff --git a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
index 63365ab..5ce0983 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp
@@ -1,9 +1,8 @@
 //===- MachineInstrBundleIteratorTest.cpp ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp
index 73d3d25..67d0c59 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -1,12 +1,12 @@
 //===- MachineInstrTest.cpp -----------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
@@ -44,11 +44,63 @@
   bool hasFP(const MachineFunction &MF) const override { return false; }
 };
 
+static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr};
+
+class BogusRegisterInfo : public TargetRegisterInfo {
+public:
+  BogusRegisterInfo()
+      : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses,
+                           nullptr, nullptr, LaneBitmask(~0u), nullptr) {
+    InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr,
+                       nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr);
+  }
+
+  const MCPhysReg *
+  getCalleeSavedRegs(const MachineFunction *MF) const override {
+    return nullptr;
+  }
+  ArrayRef<const uint32_t *> getRegMasks() const override { return None; }
+  ArrayRef<const char *> getRegMaskNames() const override { return None; }
+  BitVector getReservedRegs(const MachineFunction &MF) const override {
+    return BitVector();
+  }
+  const RegClassWeight &
+  getRegClassWeight(const TargetRegisterClass *RC) const override {
+    static RegClassWeight Bogus{1, 16};
+    return Bogus;
+  }
+  unsigned getRegUnitWeight(unsigned RegUnit) const override { return 1; }
+  unsigned getNumRegPressureSets() const override { return 0; }
+  const char *getRegPressureSetName(unsigned Idx) const override {
+    return "bogus";
+  }
+  unsigned getRegPressureSetLimit(const MachineFunction &MF,
+                                  unsigned Idx) const override {
+    return 0;
+  }
+  const int *
+  getRegClassPressureSets(const TargetRegisterClass *RC) const override {
+    static const int Bogus[] = {0, -1};
+    return &Bogus[0];
+  }
+  const int *getRegUnitPressureSets(unsigned RegUnit) const override {
+    static const int Bogus[] = {0, -1};
+    return &Bogus[0];
+  }
+
+  Register getFrameRegister(const MachineFunction &MF) const override {
+    return 0;
+  }
+  void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
+                           unsigned FIOperandNum,
+                           RegScavenger *RS = nullptr) const override {}
+};
+
 class BogusSubtarget : public TargetSubtargetInfo {
 public:
   BogusSubtarget(TargetMachine &TM)
       : TargetSubtargetInfo(Triple(""), "", "", {}, {}, nullptr, nullptr,
-                            nullptr, nullptr, nullptr, nullptr, nullptr),
+                            nullptr, nullptr, nullptr, nullptr),
         FL(), TL(TM) {}
   ~BogusSubtarget() override {}
 
@@ -58,8 +110,11 @@
 
   const TargetInstrInfo *getInstrInfo() const override { return &TII; }
 
+  const TargetRegisterInfo *getRegisterInfo() const override { return &TRI; }
+
 private:
   BogusFrameLowering FL;
+  BogusRegisterInfo TRI;
   BogusTargetLowering TL;
   TargetInstrInfo TII;
 };
@@ -266,11 +321,46 @@
 
   std::string str;
   raw_string_ostream OS(str);
-  MI->print(OS);
+  MI->print(OS, /*IsStandalone*/true, /*SkipOpers*/false, /*SkipDebugLoc*/false,
+            /*AddNewLine*/false);
   ASSERT_TRUE(
       StringRef(OS.str()).startswith("$noreg = UNKNOWN debug-location "));
   ASSERT_TRUE(
       StringRef(OS.str()).endswith("filename:1:5"));
 }
 
+TEST(MachineInstrSpan, DistanceBegin) {
+  auto MF = createMachineFunction();
+  auto MBB = MF->CreateMachineBasicBlock();
+
+  MCInstrDesc MCID = {0, 0,       0,       0,       0, 0,
+                      0, nullptr, nullptr, nullptr, 0, nullptr};
+
+  auto MII = MBB->begin();
+  MachineInstrSpan MIS(MII, MBB);
+  ASSERT_TRUE(MIS.empty());
+
+  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
+  MBB->insert(MII, MI);
+  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
+}
+
+TEST(MachineInstrSpan, DistanceEnd) {
+  auto MF = createMachineFunction();
+  auto MBB = MF->CreateMachineBasicBlock();
+
+  MCInstrDesc MCID = {0, 0,       0,       0,       0, 0,
+                      0, nullptr, nullptr, nullptr, 0, nullptr};
+
+  auto MII = MBB->end();
+  MachineInstrSpan MIS(MII, MBB);
+  ASSERT_TRUE(MIS.empty());
+
+  auto MI = MF->CreateMachineInstr(MCID, DebugLoc());
+  MBB->insert(MII, MI);
+  ASSERT_TRUE(std::distance(MIS.begin(), MII) == 1);
+}
+
+static_assert(is_trivially_copyable<MCOperand>::value, "trivially copyable");
+
 } // end namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp
index 53ec5ae..faa471f 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/MachineOperandTest.cpp
@@ -1,9 +1,8 @@
 //===- MachineOperandTest.cpp ---------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -399,4 +398,14 @@
   ASSERT_TRUE(OS.str() == "intpred(eq)");
 }
 
+TEST(MachineOperandTest, HashValue) {
+  char SymName1[] = "test";
+  char SymName2[] = "test";
+  MachineOperand MO1 = MachineOperand::CreateES(SymName1);
+  MachineOperand MO2 = MachineOperand::CreateES(SymName2);
+  ASSERT_NE(SymName1, SymName2);
+  ASSERT_EQ(hash_value(MO1), hash_value(MO2));
+  ASSERT_TRUE(MO1.isIdenticalTo(MO2));
+}
+
 } // end namespace
diff --git a/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp
index 20b3fb1..3dd3bec 100644
--- a/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp
+++ b/src/llvm-project/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp
@@ -1,9 +1,8 @@
 //===-------- llvm/unittest/CodeGen/ScalableVectorMVTsTest.cpp ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/CodeGen/TargetOptionsTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/TargetOptionsTest.cpp
new file mode 100644
index 0000000..6b4d3ed
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/TargetOptionsTest.cpp
@@ -0,0 +1,76 @@
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace llvm {
+  void initializeTestPassPass(PassRegistry &);
+}
+
+namespace {
+
+void initLLVM() {
+  InitializeAllTargets();
+  InitializeAllTargetMCs();
+  InitializeAllAsmPrinters();
+  InitializeAllAsmParsers();
+
+  PassRegistry *Registry = PassRegistry::getPassRegistry();
+  initializeCore(*Registry);
+  initializeCodeGen(*Registry);
+}
+
+/// Create a TargetMachine. We need a target that doesn't have IPRA enabled by
+/// default. That turns out to be all targets at the moment, so just use X86.
+std::unique_ptr<TargetMachine> createTargetMachine(bool EnableIPRA) {
+  Triple TargetTriple("x86_64--");
+  std::string Error;
+  const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
+  if (!T)
+    return nullptr;
+
+  TargetOptions Options;
+  Options.EnableIPRA = EnableIPRA;
+  return std::unique_ptr<TargetMachine>(T->createTargetMachine(
+      "X86", "", "", Options, None, None, CodeGenOpt::Aggressive));
+}
+
+typedef std::function<void(bool)> TargetOptionsTest;
+
+static void targetOptionsTest(bool EnableIPRA) {
+  std::unique_ptr<TargetMachine> TM = createTargetMachine(EnableIPRA);
+  // This test is designed for the X86 backend; stop if it is not available.
+  if (!TM)
+    return;
+  legacy::PassManager PM;
+  LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get());
+
+  TargetPassConfig *TPC = LLVMTM->createPassConfig(PM);
+  (void)TPC;
+
+  ASSERT_TRUE(TM->Options.EnableIPRA == EnableIPRA);
+
+  delete TPC;
+}
+
+} // End of anonymous namespace.
+
+TEST(TargetOptionsTest, IPRASetToOff) {
+  targetOptionsTest(false);
+}
+
+TEST(TargetOptionsTest, IPRASetToOn) {
+  targetOptionsTest(true);
+}
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  initLLVM();
+  return RUN_ALL_TESTS();
+}
diff --git a/src/llvm-project/llvm/unittests/CodeGen/TypeTraitsTest.cpp b/src/llvm-project/llvm/unittests/CodeGen/TypeTraitsTest.cpp
new file mode 100644
index 0000000..840375b
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/CodeGen/TypeTraitsTest.cpp
@@ -0,0 +1,25 @@
+//===- llvm/unittest/CodeGen/TypeTraitsTest.cpp --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/RegisterPressure.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+#if __has_feature(is_trivially_copyable) || (defined(__GNUC__) && __GNUC__ >= 5)
+static_assert(is_trivially_copyable<PressureChange>::value, "trivially copyable");
+static_assert(is_trivially_copyable<SDep>::value, "trivially copyable");
+static_assert(is_trivially_copyable<SDValue>::value, "trivially copyable");
+static_assert(is_trivially_copyable<SlotIndex>::value, "trivially copyable");
+static_assert(is_trivially_copyable<IdentifyingPassPtr>::value, "trivially copyable");
+#endif
+
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt b/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt
index 579fdb2..0a0a114 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_subdirectory(CodeView)
 add_subdirectory(DWARF)
+add_subdirectory(GSYM)
 add_subdirectory(MSF)
 add_subdirectory(PDB)
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
index c84eae32..ff01ef7 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/CodeView/RandomAccessVisitorTest.cpp -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -43,8 +42,6 @@
 }
 
 inline bool operator==(const CVType &R1, const CVType &R2) {
-  if (R1.Type != R2.Type)
-    return false;
   if (R1.RecordData != R2.RecordData)
     return false;
   return true;
@@ -108,7 +105,7 @@
       GlobalState->Records.push_back(AR);
       GlobalState->Indices.push_back(Builder.writeLeafType(AR));
 
-      CVType Type(TypeLeafKind::LF_ARRAY, Builder.records().back());
+      CVType Type(Builder.records().back());
       GlobalState->TypeVector.push_back(Type);
 
       GlobalState->AllOffsets.push_back(
@@ -370,11 +367,10 @@
   TypeIndex IndexOne = Builder.writeLeafType(Modifier);
 
   // set up a type stream that refers to the above two serialized records.
-  std::vector<CVType> TypeArray;
-  TypeArray.push_back(
-      CVType(static_cast<TypeLeafKind>(Class.Kind), Builder.records()[0]));
-  TypeArray.push_back(
-      CVType(static_cast<TypeLeafKind>(Modifier.Kind), Builder.records()[1]));
+  std::vector<CVType> TypeArray = {
+      {Builder.records()[0]},
+      {Builder.records()[1]},
+  };
   BinaryItemStream<CVType> ItemStream(llvm::support::little);
   ItemStream.setItems(TypeArray);
   VarStreamArray<CVType> TypeStream(ItemStream);
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp
index 5b9dadf..8b9dc7a 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeHashingTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/CodeView/TypeHashingTest.cpp ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
index 1b89160..d011db9 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
index ffbde2d..e2631af 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/DWARFDebugInfoTest.cpp ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -42,7 +41,7 @@
 
 template <uint16_t Version, class AddrType, class RefAddrType>
 void TestAllForms() {
-  Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -456,7 +455,7 @@
 }
 
 template <uint16_t Version, class AddrType> void TestChildren() {
-  Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -586,7 +585,7 @@
 }
 
 template <uint16_t Version, class AddrType> void TestReferences() {
-  Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -836,7 +835,7 @@
 }
 
 template <uint16_t Version, class AddrType> void TestAddresses() {
-  Triple Triple = getHostTripleForAddrSize(sizeof(AddrType));
+  Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1008,7 +1007,7 @@
 }
 
 TEST(DWARFDebugInfo, TestStringOffsets) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1072,7 +1071,7 @@
 }
 
 TEST(DWARFDebugInfo, TestEmptyStringOffsets) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1101,7 +1100,7 @@
 }
 
 TEST(DWARFDebugInfo, TestRelations) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1288,7 +1287,7 @@
 }
 
 TEST(DWARFDebugInfo, TestChildIterators) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1402,7 +1401,7 @@
 }
 
 TEST(DWARFDebugInfo, TestAttributeIterators) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1464,7 +1463,7 @@
 }
 
 TEST(DWARFDebugInfo, TestFindRecurse) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1556,134 +1555,129 @@
 TEST(DWARFDebugInfo, TestDwarfToFunctions) {
   // Test all of the dwarf::toXXX functions that take a
   // Optional<DWARFFormValue> and extract the values from it.
-  DWARFFormValue FormVal;
   uint64_t InvalidU64 = 0xBADBADBADBADBADB;
   int64_t InvalidS64 = 0xBADBADBADBADBADB;
+
   // First test that we don't get valid values back when using an optional with
   // no value.
-  Optional<DWARFFormValue> FormValOpt;
-  EXPECT_FALSE(toString(FormValOpt).hasValue());
-  EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toReference(FormValOpt).hasValue());
-  EXPECT_FALSE(toSigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toAddress(FormValOpt).hasValue());
-  EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
-  EXPECT_FALSE(toBlock(FormValOpt).hasValue());
-  EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
-  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidS64));
+  Optional<DWARFFormValue> FormValOpt1 = DWARFFormValue();
+  EXPECT_FALSE(toString(FormValOpt1).hasValue());
+  EXPECT_FALSE(toUnsigned(FormValOpt1).hasValue());
+  EXPECT_FALSE(toReference(FormValOpt1).hasValue());
+  EXPECT_FALSE(toSigned(FormValOpt1).hasValue());
+  EXPECT_FALSE(toAddress(FormValOpt1).hasValue());
+  EXPECT_FALSE(toSectionOffset(FormValOpt1).hasValue());
+  EXPECT_FALSE(toBlock(FormValOpt1).hasValue());
+  EXPECT_EQ(nullptr, toString(FormValOpt1, nullptr));
+  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt1, InvalidU64));
+  EXPECT_EQ(InvalidU64, toReference(FormValOpt1, InvalidU64));
+  EXPECT_EQ(InvalidU64, toAddress(FormValOpt1, InvalidU64));
+  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt1, InvalidU64));
+  EXPECT_EQ(InvalidS64, toSigned(FormValOpt1, InvalidS64));
 
   // Test successful and unsuccessful address decoding.
   uint64_t Address = 0x100000000ULL;
-  FormVal.setForm(DW_FORM_addr);
-  FormVal.setUValue(Address);
-  FormValOpt = FormVal;
+  Optional<DWARFFormValue> FormValOpt2 =
+      DWARFFormValue::createFromUValue(DW_FORM_addr, Address);
 
-  EXPECT_FALSE(toString(FormValOpt).hasValue());
-  EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toReference(FormValOpt).hasValue());
-  EXPECT_FALSE(toSigned(FormValOpt).hasValue());
-  EXPECT_TRUE(toAddress(FormValOpt).hasValue());
-  EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
-  EXPECT_FALSE(toBlock(FormValOpt).hasValue());
-  EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
-  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
-  EXPECT_EQ(Address, toAddress(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64));
+  EXPECT_FALSE(toString(FormValOpt2).hasValue());
+  EXPECT_FALSE(toUnsigned(FormValOpt2).hasValue());
+  EXPECT_FALSE(toReference(FormValOpt2).hasValue());
+  EXPECT_FALSE(toSigned(FormValOpt2).hasValue());
+  EXPECT_TRUE(toAddress(FormValOpt2).hasValue());
+  EXPECT_FALSE(toSectionOffset(FormValOpt2).hasValue());
+  EXPECT_FALSE(toBlock(FormValOpt2).hasValue());
+  EXPECT_EQ(nullptr, toString(FormValOpt2, nullptr));
+  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt2, InvalidU64));
+  EXPECT_EQ(InvalidU64, toReference(FormValOpt2, InvalidU64));
+  EXPECT_EQ(Address, toAddress(FormValOpt2, InvalidU64));
+  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt2, InvalidU64));
+  EXPECT_EQ(InvalidS64, toSigned(FormValOpt2, InvalidU64));
 
   // Test successful and unsuccessful unsigned constant decoding.
   uint64_t UData8 = 0x1020304050607080ULL;
-  FormVal.setForm(DW_FORM_udata);
-  FormVal.setUValue(UData8);
-  FormValOpt = FormVal;
+  Optional<DWARFFormValue> FormValOpt3 =
+      DWARFFormValue::createFromUValue(DW_FORM_udata, UData8);
 
-  EXPECT_FALSE(toString(FormValOpt).hasValue());
-  EXPECT_TRUE(toUnsigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toReference(FormValOpt).hasValue());
-  EXPECT_TRUE(toSigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toAddress(FormValOpt).hasValue());
-  EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
-  EXPECT_FALSE(toBlock(FormValOpt).hasValue());
-  EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
-  EXPECT_EQ(UData8, toUnsigned(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
-  EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt, InvalidU64));
+  EXPECT_FALSE(toString(FormValOpt3).hasValue());
+  EXPECT_TRUE(toUnsigned(FormValOpt3).hasValue());
+  EXPECT_FALSE(toReference(FormValOpt3).hasValue());
+  EXPECT_TRUE(toSigned(FormValOpt3).hasValue());
+  EXPECT_FALSE(toAddress(FormValOpt3).hasValue());
+  EXPECT_FALSE(toSectionOffset(FormValOpt3).hasValue());
+  EXPECT_FALSE(toBlock(FormValOpt3).hasValue());
+  EXPECT_EQ(nullptr, toString(FormValOpt3, nullptr));
+  EXPECT_EQ(UData8, toUnsigned(FormValOpt3, InvalidU64));
+  EXPECT_EQ(InvalidU64, toReference(FormValOpt3, InvalidU64));
+  EXPECT_EQ(InvalidU64, toAddress(FormValOpt3, InvalidU64));
+  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt3, InvalidU64));
+  EXPECT_EQ((int64_t)UData8, toSigned(FormValOpt3, InvalidU64));
 
   // Test successful and unsuccessful reference decoding.
   uint32_t RefData = 0x11223344U;
-  FormVal.setForm(DW_FORM_ref_addr);
-  FormVal.setUValue(RefData);
-  FormValOpt = FormVal;
+  Optional<DWARFFormValue> FormValOpt4 =
+      DWARFFormValue::createFromUValue(DW_FORM_ref_addr, RefData);
 
-  EXPECT_FALSE(toString(FormValOpt).hasValue());
-  EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
-  EXPECT_TRUE(toReference(FormValOpt).hasValue());
-  EXPECT_FALSE(toSigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toAddress(FormValOpt).hasValue());
-  EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
-  EXPECT_FALSE(toBlock(FormValOpt).hasValue());
-  EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
-  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
-  EXPECT_EQ(RefData, toReference(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64));
+  EXPECT_FALSE(toString(FormValOpt4).hasValue());
+  EXPECT_FALSE(toUnsigned(FormValOpt4).hasValue());
+  EXPECT_TRUE(toReference(FormValOpt4).hasValue());
+  EXPECT_FALSE(toSigned(FormValOpt4).hasValue());
+  EXPECT_FALSE(toAddress(FormValOpt4).hasValue());
+  EXPECT_FALSE(toSectionOffset(FormValOpt4).hasValue());
+  EXPECT_FALSE(toBlock(FormValOpt4).hasValue());
+  EXPECT_EQ(nullptr, toString(FormValOpt4, nullptr));
+  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt4, InvalidU64));
+  EXPECT_EQ(RefData, toReference(FormValOpt4, InvalidU64));
+  EXPECT_EQ(InvalidU64, toAddress(FormValOpt4, InvalidU64));
+  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt4, InvalidU64));
+  EXPECT_EQ(InvalidS64, toSigned(FormValOpt4, InvalidU64));
 
   // Test successful and unsuccessful signed constant decoding.
   int64_t SData8 = 0x1020304050607080ULL;
-  FormVal.setForm(DW_FORM_udata);
-  FormVal.setSValue(SData8);
-  FormValOpt = FormVal;
+  Optional<DWARFFormValue> FormValOpt5 =
+      DWARFFormValue::createFromSValue(DW_FORM_udata, SData8);
 
-  EXPECT_FALSE(toString(FormValOpt).hasValue());
-  EXPECT_TRUE(toUnsigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toReference(FormValOpt).hasValue());
-  EXPECT_TRUE(toSigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toAddress(FormValOpt).hasValue());
-  EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
-  EXPECT_FALSE(toBlock(FormValOpt).hasValue());
-  EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
-  EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
-  EXPECT_EQ(SData8, toSigned(FormValOpt, InvalidU64));
+  EXPECT_FALSE(toString(FormValOpt5).hasValue());
+  EXPECT_TRUE(toUnsigned(FormValOpt5).hasValue());
+  EXPECT_FALSE(toReference(FormValOpt5).hasValue());
+  EXPECT_TRUE(toSigned(FormValOpt5).hasValue());
+  EXPECT_FALSE(toAddress(FormValOpt5).hasValue());
+  EXPECT_FALSE(toSectionOffset(FormValOpt5).hasValue());
+  EXPECT_FALSE(toBlock(FormValOpt5).hasValue());
+  EXPECT_EQ(nullptr, toString(FormValOpt5, nullptr));
+  EXPECT_EQ((uint64_t)SData8, toUnsigned(FormValOpt5, InvalidU64));
+  EXPECT_EQ(InvalidU64, toReference(FormValOpt5, InvalidU64));
+  EXPECT_EQ(InvalidU64, toAddress(FormValOpt5, InvalidU64));
+  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt5, InvalidU64));
+  EXPECT_EQ(SData8, toSigned(FormValOpt5, InvalidU64));
 
   // Test successful and unsuccessful block decoding.
   uint8_t Data[] = { 2, 3, 4 };
   ArrayRef<uint8_t> Array(Data);
-  FormVal.setForm(DW_FORM_block1);
-  FormVal.setBlockValue(Array);
-  FormValOpt = FormVal;
+  Optional<DWARFFormValue> FormValOpt6 =
+      DWARFFormValue::createFromBlockValue(DW_FORM_block1, Array);
 
-  EXPECT_FALSE(toString(FormValOpt).hasValue());
-  EXPECT_FALSE(toUnsigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toReference(FormValOpt).hasValue());
-  EXPECT_FALSE(toSigned(FormValOpt).hasValue());
-  EXPECT_FALSE(toAddress(FormValOpt).hasValue());
-  EXPECT_FALSE(toSectionOffset(FormValOpt).hasValue());
-  auto BlockOpt = toBlock(FormValOpt);
+  EXPECT_FALSE(toString(FormValOpt6).hasValue());
+  EXPECT_FALSE(toUnsigned(FormValOpt6).hasValue());
+  EXPECT_FALSE(toReference(FormValOpt6).hasValue());
+  EXPECT_FALSE(toSigned(FormValOpt6).hasValue());
+  EXPECT_FALSE(toAddress(FormValOpt6).hasValue());
+  EXPECT_FALSE(toSectionOffset(FormValOpt6).hasValue());
+  auto BlockOpt = toBlock(FormValOpt6);
   EXPECT_TRUE(BlockOpt.hasValue());
   EXPECT_EQ(*BlockOpt, Array);
-  EXPECT_EQ(nullptr, toString(FormValOpt, nullptr));
-  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toReference(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toAddress(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt, InvalidU64));
-  EXPECT_EQ(InvalidS64, toSigned(FormValOpt, InvalidU64));
+  EXPECT_EQ(nullptr, toString(FormValOpt6, nullptr));
+  EXPECT_EQ(InvalidU64, toUnsigned(FormValOpt6, InvalidU64));
+  EXPECT_EQ(InvalidU64, toReference(FormValOpt6, InvalidU64));
+  EXPECT_EQ(InvalidU64, toAddress(FormValOpt6, InvalidU64));
+  EXPECT_EQ(InvalidU64, toSectionOffset(FormValOpt6, InvalidU64));
+  EXPECT_EQ(InvalidS64, toSigned(FormValOpt6, InvalidU64));
 
   // Test
 }
 
 TEST(DWARFDebugInfo, TestFindAttrs) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -1746,7 +1740,7 @@
 }
 
 TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) {
-  Triple Triple = getHostTripleForAddrSize(sizeof(void *));
+  Triple Triple = getNormalizedDefaultTargetTriple();
   if (!isConfigurationSupported(Triple))
     return;
 
@@ -2989,72 +2983,34 @@
   VerifySuccess(*DwarfContext);
 }
 
-TEST(DWARFDebugInfo, TestDwarfRangesContains) {
-  DWARFAddressRange R(0x10, 0x20);
-
-  //----------------------------------------------------------------------
-  // Test ranges that start before R...
-  //----------------------------------------------------------------------
-  // Other range ends before start of R
-  ASSERT_FALSE(R.contains({0x0f, 0x10}));
-  // Other range end address is start of a R
-  ASSERT_FALSE(R.contains({0x0f, 0x11}));
-  // Other range end address is at and of R
-  ASSERT_FALSE(R.contains({0x0f, 0x20}));
-  // Other range end address is past end of R
-  ASSERT_FALSE(R.contains({0x0f, 0x40}));
-
-  //----------------------------------------------------------------------
-  // Test ranges that start at R's start address
-  //----------------------------------------------------------------------
-  // Ensure empty ranges matches
-  ASSERT_TRUE(R.contains({0x10, 0x10}));
-  // 1 byte of Range
-  ASSERT_TRUE(R.contains({0x10, 0x11}));
-  // same as Range
-  ASSERT_TRUE(R.contains({0x10, 0x20}));
-  // 1 byte past Range
-  ASSERT_FALSE(R.contains({0x10, 0x21}));
-
-  //----------------------------------------------------------------------
-  // Test ranges that start inside Range
-  //----------------------------------------------------------------------
-  // empty in range
-  ASSERT_TRUE(R.contains({0x11, 0x11}));
-  // all in Range
-  ASSERT_TRUE(R.contains({0x11, 0x1f}));
-  // ends at end of Range
-  ASSERT_TRUE(R.contains({0x11, 0x20}));
-  // ends past Range
-  ASSERT_FALSE(R.contains({0x11, 0x21}));
-
-  //----------------------------------------------------------------------
-  // Test ranges that start at last bytes of Range
-  //----------------------------------------------------------------------
-  // ends at end of Range
-  ASSERT_TRUE(R.contains({0x1f, 0x20}));
-  // ends past Range
-  ASSERT_FALSE(R.contains({0x1f, 0x21}));
-
-  //----------------------------------------------------------------------
-  // Test ranges that start after Range
-  //----------------------------------------------------------------------
-  // empty considered in Range
-  ASSERT_TRUE(R.contains({0x20, 0x20}));
-  // valid past Range
-  ASSERT_FALSE(R.contains({0x20, 0x21}));
-}
-
 TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) {
-  DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}});
+  DWARFVerifier::DieRangeInfo Empty;
+  ASSERT_TRUE(Empty.contains(Empty));
 
+  DWARFVerifier::DieRangeInfo Ranges(
+      {{0x10, 0x20}, {0x30, 0x40}, {0x40, 0x50}});
+
+  ASSERT_TRUE(Ranges.contains(Empty));
   ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}}));
-  ASSERT_FALSE(Ranges.contains({{{0x20, 0x30}}}));
-  ASSERT_FALSE(Ranges.contains({{{0x40, 0x41}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x20}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x21}}}));
+
+  // Test ranges that start at R's start address
+  ASSERT_TRUE(Ranges.contains({{{0x10, 0x10}}}));
+  ASSERT_TRUE(Ranges.contains({{{0x10, 0x11}}}));
   ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x10, 0x21}}}));
+
   ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}}));
+
+  // Test ranges that start at last bytes of Range
   ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}}));
-  ASSERT_TRUE(Ranges.contains({{{0x30, 0x40}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x1f, 0x21}}}));
+
+  // Test ranges that start after Range
+  ASSERT_TRUE(Ranges.contains({{{0x20, 0x20}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x20, 0x21}}}));
+
   ASSERT_TRUE(Ranges.contains({{{0x31, 0x32}}}));
   ASSERT_TRUE(Ranges.contains({{{0x3f, 0x40}}}));
   ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}, {0x30, 0x40}}}));
@@ -3067,7 +3023,10 @@
                                  {0x31, 0x32},
                                  {0x32, 0x33}}}));
   ASSERT_FALSE(Ranges.contains(
-      {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x41}}}));
+      {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x51}}}));
+  ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x30, 0x50}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x30, 0x51}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x50, 0x51}}}));
 }
 
 namespace {
@@ -3194,6 +3153,9 @@
   AssertRangesIntersect(Ranges, {{0x3f, 0x40}});
   // Test range that starts at end of second range
   AssertRangesDontIntersect(Ranges, {{0x40, 0x41}});
+
+  AssertRangesDontIntersect(Ranges, {{0x20, 0x21}, {0x2f, 0x30}});
+  AssertRangesIntersect(Ranges, {{0x20, 0x21}, {0x2f, 0x31}});
 }
 
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
index 03586ca..ce7c252 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
@@ -1,9 +1,8 @@
 //===- DWARFDebugLineTest.cpp ---------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -38,7 +37,7 @@
   }
 
   bool setupGenerator(uint16_t Version = 4) {
-    Triple T = getHostTripleForAddrSize(8);
+    Triple T = getDefaultTargetTripleForAddrSize(8);
     if (!isConfigurationSupported(T))
       return false;
     auto ExpectedGenerator = Generator::create(T, Version);
@@ -51,8 +50,9 @@
     Context = createContext();
     assert(Context != nullptr && "test state is not valid");
     const DWARFObject &Obj = Context->getDWARFObj();
-    LineData = DWARFDataExtractor(Obj, Obj.getLineSection(),
-                                  sys::IsLittleEndianHost, 8);
+    LineData = DWARFDataExtractor(
+        Obj, Obj.getLineSection(),
+        getDefaultTargetTripleForAddrSize(8).isLittleEndian(), 8);
   }
 
   std::unique_ptr<DWARFContext> createContext() {
@@ -291,13 +291,13 @@
     return;
 
   LineTable &LT = Gen->addLineTable();
-  LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
+  LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
 
   generate();
 
   checkGetOrParseLineTableEmitsError(
       "parsing line table prologue at offset 0x00000000 unsupported reserved "
-      "unit length found of value 0xffffff00");
+      "unit length found of value 0xfffffff0");
 }
 
 TEST_F(DebugLineBasicFixture, ErrorForLowVersion) {
@@ -532,7 +532,7 @@
     return;
 
   LineTable &LT = Gen->addLineTable();
-  LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
+  LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
   Gen->addLineTable();
   generate();
 
@@ -544,7 +544,7 @@
   EXPECT_FALSE(Recoverable);
 
   checkError("parsing line table prologue at offset 0x00000000 unsupported "
-             "reserved unit length found of value 0xffffff00",
+             "reserved unit length found of value 0xfffffff0",
              std::move(Unrecoverable));
 }
 
@@ -553,7 +553,7 @@
     return;
 
   LineTable &LT = Gen->addLineTable();
-  LT.setCustomPrologue({{0xffffff00, LineTable::Long}});
+  LT.setCustomPrologue({{0xfffffff0, LineTable::Long}});
   Gen->addLineTable();
   generate();
 
@@ -564,7 +564,7 @@
   EXPECT_TRUE(Parser.done());
 
   checkError("parsing line table prologue at offset 0x00000000 unsupported "
-             "reserved unit length found of value 0xffffff00",
+             "reserved unit length found of value 0xfffffff0",
              std::move(Unrecoverable));
 }
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
index 582b580..c40db07 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/DWARFFormValueTest.cpp ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
index 9732766..468eaa2 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.cpp
@@ -1,9 +1,8 @@
 //===--- unittests/DebugInfo/DWARF/DwarfGenerator.cpp -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -184,11 +183,11 @@
   P.LineRange = 14;
   P.OpcodeBase = 13;
   P.StandardOpcodeLengths = {0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1};
-  P.IncludeDirectories.push_back(DWARFFormValue(DW_FORM_string));
-  P.IncludeDirectories.back().setPValue("a dir");
+  P.IncludeDirectories.push_back(
+      DWARFFormValue::createFromPValue(DW_FORM_string, "a dir"));
   P.FileNames.push_back(DWARFDebugLine::FileNameEntry());
-  P.FileNames.back().Name.setPValue("a file");
-  P.FileNames.back().Name.setForm(DW_FORM_string);
+  P.FileNames.back().Name =
+      DWARFFormValue::createFromPValue(DW_FORM_string, "a file");
   return P;
 }
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h
index 40ecaa9..2f95e29 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h
@@ -1,9 +1,8 @@
 //===--- unittests/DebugInfo/DWARF/DwarfGenerator.h -------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp
index ef43c13..249cfb4 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.cpp
@@ -1,15 +1,15 @@
 //===--- unittests/DebugInfo/DWARF/DwarfUtils.cpp ---------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "DwarfUtils.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Host.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
 
@@ -26,9 +26,20 @@
   }
 }
 
-Triple llvm::dwarf::utils::getHostTripleForAddrSize(uint8_t AddrSize) {
-  Triple T(Triple::normalize(LLVM_HOST_TRIPLE));
+Triple llvm::dwarf::utils::getNormalizedDefaultTargetTriple() {
+  Triple T(Triple::normalize(sys::getDefaultTargetTriple()));
 
+  return T;
+}
+
+Triple llvm::dwarf::utils::getDefaultTargetTripleForAddrSize(uint8_t AddrSize) {
+  Triple T = getNormalizedDefaultTargetTriple();
+
+  assert((AddrSize == 4 || AddrSize == 8) &&
+         "Only 32-bit/64-bit address size variants are supported");
+
+  // If a 32-bit/64-bit address size was specified, try to convert the triple
+  // if it is for the wrong variant.
   if (AddrSize == 8 && T.isArch32Bit())
     return T.get64BitArchVariant();
   if (AddrSize == 4 && T.isArch64Bit())
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h
index 3d80456..036071e 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h
+++ b/src/llvm-project/llvm/unittests/DebugInfo/DWARF/DwarfUtils.h
@@ -1,9 +1,8 @@
 //===--- unittests/DebugInfo/DWARF/DwarfUtils.h -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -19,7 +18,8 @@
 namespace dwarf {
 namespace utils {
 
-Triple getHostTripleForAddrSize(uint8_t AddrSize);
+Triple getDefaultTargetTripleForAddrSize(uint8_t AddrSize);
+Triple getNormalizedDefaultTargetTriple();
 bool isConfigurationSupported(Triple &T);
 
 } // end namespace utils
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/GSYM/CMakeLists.txt b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/CMakeLists.txt
new file mode 100644
index 0000000..fb9d5e5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/CMakeLists.txt
@@ -0,0 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+  DebugInfoGSYM
+  Support
+  )
+
+add_llvm_unittest(DebugInfoGSYMTests
+  GSYMTest.cpp
+  )
+
+target_link_libraries(DebugInfoGSYMTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
new file mode 100644
index 0000000..dc34691
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
@@ -0,0 +1,381 @@
+//===- llvm/unittest/DebugInfo/GSYMTest.cpp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/DebugInfo/GSYM/StringTable.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest.h"
+#include <string>
+
+using namespace llvm;
+using namespace gsym;
+
+TEST(GSYMTest, TestFileEntry) {
+  // Make sure default constructed GSYM FileEntry has zeroes in the
+  // directory and basename string table indexes.
+  FileEntry empty1;
+  FileEntry empty2;
+  EXPECT_EQ(empty1.Dir, 0u);
+  EXPECT_EQ(empty1.Base, 0u);
+  // Verify equality operator works
+  FileEntry a1(10, 30);
+  FileEntry a2(10, 30);
+  FileEntry b(10, 40);
+  EXPECT_EQ(empty1, empty2);
+  EXPECT_EQ(a1, a2);
+  EXPECT_NE(a1, b);
+  EXPECT_NE(a1, empty1);
+  // Test we can use llvm::gsym::FileEntry in llvm::DenseMap.
+  DenseMap<FileEntry, uint32_t> EntryToIndex;
+  constexpr uint32_t Index1 = 1;
+  constexpr uint32_t Index2 = 1;
+  auto R = EntryToIndex.insert(std::make_pair(a1, Index1));
+  EXPECT_TRUE(R.second);
+  EXPECT_EQ(R.first->second, Index1);
+  R = EntryToIndex.insert(std::make_pair(a1, Index1));
+  EXPECT_FALSE(R.second);
+  EXPECT_EQ(R.first->second, Index1);
+  R = EntryToIndex.insert(std::make_pair(b, Index2));
+  EXPECT_TRUE(R.second);
+  EXPECT_EQ(R.first->second, Index2);
+  R = EntryToIndex.insert(std::make_pair(a1, Index2));
+  EXPECT_FALSE(R.second);
+  EXPECT_EQ(R.first->second, Index2);
+}
+
+TEST(GSYMTest, TestFunctionInfo) {
+  // Test GSYM FunctionInfo structs and functionality.
+  FunctionInfo invalid;
+  EXPECT_FALSE(invalid.isValid());
+  EXPECT_FALSE(invalid.hasRichInfo());
+  const uint64_t StartAddr = 0x1000;
+  const uint64_t EndAddr = 0x1100;
+  const uint64_t Size = EndAddr - StartAddr;
+  const uint32_t NameOffset = 30;
+  FunctionInfo FI(StartAddr, Size, NameOffset);
+  EXPECT_TRUE(FI.isValid());
+  EXPECT_FALSE(FI.hasRichInfo());
+  EXPECT_EQ(FI.startAddress(), StartAddr);
+  EXPECT_EQ(FI.endAddress(), EndAddr);
+  EXPECT_EQ(FI.size(), Size);
+  const uint32_t FileIdx = 1;
+  const uint32_t Line = 12;
+  FI.Lines.push_back(LineEntry(StartAddr, FileIdx, Line));
+  EXPECT_TRUE(FI.hasRichInfo());
+  FI.clear();
+  EXPECT_FALSE(FI.isValid());
+  EXPECT_FALSE(FI.hasRichInfo());
+
+  FunctionInfo A1(0x1000, 0x100, NameOffset);
+  FunctionInfo A2(0x1000, 0x100, NameOffset);
+  FunctionInfo B;
+  // Check == operator
+  EXPECT_EQ(A1, A2);
+  // Make sure things are not equal if they only differ by start address.
+  B = A2;
+  B.setStartAddress(0x2000);
+  EXPECT_NE(B, A2);
+  // Make sure things are not equal if they only differ by size.
+  B = A2;
+  B.setSize(0x101);
+  EXPECT_NE(B, A2);
+  // Make sure things are not equal if they only differ by name.
+  B = A2;
+  B.Name = 60;
+  EXPECT_NE(B, A2);
+  // Check < operator.
+  // Check less than where address differs.
+  B = A2;
+  B.setStartAddress(A2.startAddress() + 0x1000);
+  EXPECT_LT(A1, B);
+
+  // We use the < operator to take a variety of different FunctionInfo
+  // structs from a variety of sources: symtab, debug info, runtime info
+  // and we sort them and want the sorting to allow us to quickly get the
+  // best version of a function info.
+  FunctionInfo FISymtab(StartAddr, Size, NameOffset);
+  FunctionInfo FIWithLines(StartAddr, Size, NameOffset);
+  FIWithLines.Lines.push_back(LineEntry(StartAddr, FileIdx, Line));
+  // Test that a FunctionInfo with just a name and size is less than one
+  // that has name, size and any number of line table entries
+  EXPECT_LT(FISymtab, FIWithLines);
+
+  FunctionInfo FIWithLinesAndInline = FIWithLines;
+  FIWithLinesAndInline.Inline.Ranges.insert(
+      AddressRange(StartAddr, StartAddr + 0x10));
+  // Test that a FunctionInfo with name, size, and line entries is less than
+  // the same one with valid inline info
+  EXPECT_LT(FIWithLines, FIWithLinesAndInline);
+
+  // Test if we have an entry with lines and one with more lines for the same
+  // range, the ones with more lines is greater than the one with less.
+  FunctionInfo FIWithMoreLines = FIWithLines;
+  FIWithMoreLines.Lines.push_back(LineEntry(StartAddr, FileIdx, Line + 5));
+  EXPECT_LT(FIWithLines, FIWithMoreLines);
+
+  // Test that if we have the same number of lines we compare the line entries
+  // in the FunctionInfo.Lines vector.
+  FunctionInfo FIWithLinesWithHigherAddress = FIWithLines;
+  FIWithLinesWithHigherAddress.Lines[0].Addr += 0x10;
+  EXPECT_LT(FIWithLines, FIWithLinesWithHigherAddress);
+}
+
+TEST(GSYMTest, TestInlineInfo) {
+  // Test InlineInfo structs.
+  InlineInfo II;
+  EXPECT_FALSE(II.isValid());
+  II.Ranges.insert(AddressRange(0x1000, 0x2000));
+  // Make sure InlineInfo in valid with just an address range since
+  // top level InlineInfo objects have ranges with no name, call file
+  // or call line
+  EXPECT_TRUE(II.isValid());
+  // Make sure InlineInfo isn't after being cleared.
+  II.clear();
+  EXPECT_FALSE(II.isValid());
+
+  // Create an InlineInfo that contains the following data. The
+  // indentation of the address range indicates the parent child
+  // relationships of the InlineInfo objects:
+  //
+  // Variable    Range and values
+  // =========== ====================================================
+  // Root        [0x100-0x200) (no name, file, or line)
+  // Inline1       [0x150-0x160) Name = 1, File = 1, Line = 11
+  // Inline1Sub1     [0x152-0x155) Name = 2, File = 2, Line = 22
+  // Inline1Sub2     [0x157-0x158) Name = 3, File = 3, Line = 33
+  InlineInfo Root;
+  Root.Ranges.insert(AddressRange(0x100, 0x200));
+  InlineInfo Inline1;
+  Inline1.Ranges.insert(AddressRange(0x150, 0x160));
+  Inline1.Name = 1;
+  Inline1.CallFile = 1;
+  Inline1.CallLine = 11;
+  InlineInfo Inline1Sub1;
+  Inline1Sub1.Ranges.insert(AddressRange(0x152, 0x155));
+  Inline1Sub1.Name = 2;
+  Inline1Sub1.CallFile = 2;
+  Inline1Sub1.CallLine = 22;
+  InlineInfo Inline1Sub2;
+  Inline1Sub2.Ranges.insert(AddressRange(0x157, 0x158));
+  Inline1Sub2.Name = 3;
+  Inline1Sub2.CallFile = 3;
+  Inline1Sub2.CallLine = 33;
+  Inline1.Children.push_back(Inline1Sub1);
+  Inline1.Children.push_back(Inline1Sub2);
+  Root.Children.push_back(Inline1);
+
+  // Make sure an address that is out of range won't match
+  EXPECT_FALSE(Root.getInlineStack(0x50));
+
+  // Verify that we get no inline stacks for addresses out of [0x100-0x200)
+  EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].Start - 1));
+  EXPECT_FALSE(Root.getInlineStack(Root.Ranges[0].End));
+
+  // Verify we get no inline stack entries for addresses that are in
+  // [0x100-0x200) but not in [0x150-0x160)
+  EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].Start - 1));
+  EXPECT_FALSE(Root.getInlineStack(Inline1.Ranges[0].End));
+
+  // Verify we get one inline stack entry for addresses that are in
+  // [[0x150-0x160)) but not in [0x152-0x155) or [0x157-0x158)
+  auto InlineInfos = Root.getInlineStack(Inline1.Ranges[0].Start);
+  ASSERT_TRUE(InlineInfos);
+  ASSERT_EQ(InlineInfos->size(), 1u);
+  ASSERT_EQ(*InlineInfos->at(0), Inline1);
+  InlineInfos = Root.getInlineStack(Inline1.Ranges[0].End - 1);
+  EXPECT_TRUE(InlineInfos);
+  ASSERT_EQ(InlineInfos->size(), 1u);
+  ASSERT_EQ(*InlineInfos->at(0), Inline1);
+
+  // Verify we get two inline stack entries for addresses that are in
+  // [0x152-0x155)
+  InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].Start);
+  EXPECT_TRUE(InlineInfos);
+  ASSERT_EQ(InlineInfos->size(), 2u);
+  ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
+  ASSERT_EQ(*InlineInfos->at(1), Inline1);
+  InlineInfos = Root.getInlineStack(Inline1Sub1.Ranges[0].End - 1);
+  EXPECT_TRUE(InlineInfos);
+  ASSERT_EQ(InlineInfos->size(), 2u);
+  ASSERT_EQ(*InlineInfos->at(0), Inline1Sub1);
+  ASSERT_EQ(*InlineInfos->at(1), Inline1);
+
+  // Verify we get two inline stack entries for addresses that are in
+  // [0x157-0x158)
+  InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].Start);
+  EXPECT_TRUE(InlineInfos);
+  ASSERT_EQ(InlineInfos->size(), 2u);
+  ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
+  ASSERT_EQ(*InlineInfos->at(1), Inline1);
+  InlineInfos = Root.getInlineStack(Inline1Sub2.Ranges[0].End - 1);
+  EXPECT_TRUE(InlineInfos);
+  ASSERT_EQ(InlineInfos->size(), 2u);
+  ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2);
+  ASSERT_EQ(*InlineInfos->at(1), Inline1);
+}
+
+TEST(GSYMTest, TestLineEntry) {
+  // test llvm::gsym::LineEntry structs.
+  const uint64_t ValidAddr = 0x1000;
+  const uint64_t InvalidFileIdx = 0;
+  const uint32_t ValidFileIdx = 1;
+  const uint32_t ValidLine = 5;
+
+  LineEntry Invalid;
+  EXPECT_FALSE(Invalid.isValid());
+  // Make sure that an entry is invalid if it has a bad file index.
+  LineEntry BadFile(ValidAddr, InvalidFileIdx, ValidLine);
+  EXPECT_FALSE(BadFile.isValid());
+  // Test operators
+  LineEntry E1(ValidAddr, ValidFileIdx, ValidLine);
+  LineEntry E2(ValidAddr, ValidFileIdx, ValidLine);
+  LineEntry DifferentAddr(ValidAddr + 1, ValidFileIdx, ValidLine);
+  LineEntry DifferentFile(ValidAddr, ValidFileIdx + 1, ValidLine);
+  LineEntry DifferentLine(ValidAddr, ValidFileIdx, ValidLine + 1);
+  EXPECT_TRUE(E1.isValid());
+  EXPECT_EQ(E1, E2);
+  EXPECT_NE(E1, DifferentAddr);
+  EXPECT_NE(E1, DifferentFile);
+  EXPECT_NE(E1, DifferentLine);
+  EXPECT_LT(E1, DifferentAddr);
+}
+
+TEST(GSYMTest, TestRanges) {
+  // test llvm::gsym::AddressRange.
+  const uint64_t StartAddr = 0x1000;
+  const uint64_t EndAddr = 0x2000;
+  // Verify constructor and API to ensure it takes start and end address.
+  const AddressRange Range(StartAddr, EndAddr);
+  EXPECT_EQ(Range.size(), EndAddr - StartAddr);
+
+  // Verify llvm::gsym::AddressRange::contains().
+  EXPECT_FALSE(Range.contains(0));
+  EXPECT_FALSE(Range.contains(StartAddr - 1));
+  EXPECT_TRUE(Range.contains(StartAddr));
+  EXPECT_TRUE(Range.contains(EndAddr - 1));
+  EXPECT_FALSE(Range.contains(EndAddr));
+  EXPECT_FALSE(Range.contains(UINT64_MAX));
+
+  const AddressRange RangeSame(StartAddr, EndAddr);
+  const AddressRange RangeDifferentStart(StartAddr + 1, EndAddr);
+  const AddressRange RangeDifferentEnd(StartAddr, EndAddr + 1);
+  const AddressRange RangeDifferentStartEnd(StartAddr + 1, EndAddr + 1);
+  // Test == and != with values that are the same
+  EXPECT_EQ(Range, RangeSame);
+  EXPECT_FALSE(Range != RangeSame);
+  // Test == and != with values that are the different
+  EXPECT_NE(Range, RangeDifferentStart);
+  EXPECT_NE(Range, RangeDifferentEnd);
+  EXPECT_NE(Range, RangeDifferentStartEnd);
+  EXPECT_FALSE(Range == RangeDifferentStart);
+  EXPECT_FALSE(Range == RangeDifferentEnd);
+  EXPECT_FALSE(Range == RangeDifferentStartEnd);
+
+  // Test "bool operator<(const AddressRange &, const AddressRange &)".
+  EXPECT_FALSE(Range < RangeSame);
+  EXPECT_FALSE(RangeSame < Range);
+  EXPECT_LT(Range, RangeDifferentStart);
+  EXPECT_LT(Range, RangeDifferentEnd);
+  EXPECT_LT(Range, RangeDifferentStartEnd);
+  // Test "bool operator<(const AddressRange &, uint64_t)"
+  EXPECT_LT(Range.Start, StartAddr + 1);
+  // Test "bool operator<(uint64_t, const AddressRange &)"
+  EXPECT_LT(StartAddr - 1, Range.Start);
+
+  // Verify llvm::gsym::AddressRange::isContiguousWith() and
+  // llvm::gsym::AddressRange::intersects().
+  const AddressRange EndsBeforeRangeStart(0, StartAddr - 1);
+  const AddressRange EndsAtRangeStart(0, StartAddr);
+  const AddressRange OverlapsRangeStart(StartAddr - 1, StartAddr + 1);
+  const AddressRange InsideRange(StartAddr + 1, EndAddr - 1);
+  const AddressRange OverlapsRangeEnd(EndAddr - 1, EndAddr + 1);
+  const AddressRange StartsAtRangeEnd(EndAddr, EndAddr + 0x100);
+  const AddressRange StartsAfterRangeEnd(EndAddr + 1, EndAddr + 0x100);
+
+  EXPECT_FALSE(Range.intersects(EndsBeforeRangeStart));
+  EXPECT_FALSE(Range.intersects(EndsAtRangeStart));
+  EXPECT_TRUE(Range.intersects(OverlapsRangeStart));
+  EXPECT_TRUE(Range.intersects(InsideRange));
+  EXPECT_TRUE(Range.intersects(OverlapsRangeEnd));
+  EXPECT_FALSE(Range.intersects(StartsAtRangeEnd));
+  EXPECT_FALSE(Range.intersects(StartsAfterRangeEnd));
+
+  // Test the functions that maintain GSYM address ranges:
+  //  "bool AddressRange::contains(uint64_t Addr) const;"
+  //  "void AddressRanges::insert(const AddressRange &R);"
+  AddressRanges Ranges;
+  Ranges.insert(AddressRange(0x1000, 0x2000));
+  Ranges.insert(AddressRange(0x2000, 0x3000));
+  Ranges.insert(AddressRange(0x4000, 0x5000));
+
+  EXPECT_FALSE(Ranges.contains(0));
+  EXPECT_FALSE(Ranges.contains(0x1000 - 1));
+  EXPECT_TRUE(Ranges.contains(0x1000));
+  EXPECT_TRUE(Ranges.contains(0x2000));
+  EXPECT_TRUE(Ranges.contains(0x4000));
+  EXPECT_TRUE(Ranges.contains(0x2000 - 1));
+  EXPECT_TRUE(Ranges.contains(0x3000 - 1));
+  EXPECT_FALSE(Ranges.contains(0x3000 + 1));
+  EXPECT_TRUE(Ranges.contains(0x5000 - 1));
+  EXPECT_FALSE(Ranges.contains(0x5000 + 1));
+  EXPECT_FALSE(Ranges.contains(UINT64_MAX));
+
+  // Verify that intersecting ranges get combined
+  Ranges.clear();
+  Ranges.insert(AddressRange(0x1100, 0x1F00));
+  // Verify a wholy contained range that is added doesn't do anything.
+  Ranges.insert(AddressRange(0x1500, 0x1F00));
+  EXPECT_EQ(Ranges.size(), 1u);
+  EXPECT_EQ(Ranges[0], AddressRange(0x1100, 0x1F00));
+
+  // Verify a range that starts before and intersects gets combined.
+  Ranges.insert(AddressRange(0x1000, Ranges[0].Start + 1));
+  EXPECT_EQ(Ranges.size(), 1u);
+  EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x1F00));
+
+  // Verify a range that starts inside and extends ranges gets combined.
+  Ranges.insert(AddressRange(Ranges[0].End - 1, 0x2000));
+  EXPECT_EQ(Ranges.size(), 1u);
+  EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
+
+  // Verify that adjacent ranges don't get combined
+  Ranges.insert(AddressRange(0x2000, 0x3000));
+  EXPECT_EQ(Ranges.size(), 2u);
+  EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x2000));
+  EXPECT_EQ(Ranges[1], AddressRange(0x2000, 0x3000));
+  // Verify if we add an address range that intersects two ranges
+  // that they get combined
+  Ranges.insert(AddressRange(Ranges[0].End - 1, Ranges[1].Start + 1));
+  EXPECT_EQ(Ranges.size(), 1u);
+  EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x3000));
+
+  Ranges.insert(AddressRange(0x3000, 0x4000));
+  Ranges.insert(AddressRange(0x4000, 0x5000));
+  Ranges.insert(AddressRange(0x2000, 0x4500));
+  EXPECT_EQ(Ranges.size(), 1u);
+  EXPECT_EQ(Ranges[0], AddressRange(0x1000, 0x5000));
+}
+
+TEST(GSYMTest, TestStringTable) {
+  StringTable StrTab(StringRef("\0Hello\0World\0", 13));
+  // Test extracting strings from a string table.
+  EXPECT_EQ(StrTab.getString(0), "");
+  EXPECT_EQ(StrTab.getString(1), "Hello");
+  EXPECT_EQ(StrTab.getString(7), "World");
+  EXPECT_EQ(StrTab.getString(8), "orld");
+  // Test pointing to last NULL terminator gets empty string.
+  EXPECT_EQ(StrTab.getString(12), "");
+  // Test pointing to past end gets empty string.
+  EXPECT_EQ(StrTab.getString(13), "");
+}
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
index 1624795..f327fef 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFBuilderTest.cpp
@@ -1,9 +1,8 @@
 //===- MSFBuilderTest.cpp  Tests manipulation of MSF stream metadata ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp
index ee9ac75..68d0875 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MSFCommonTest.cpp
@@ -1,9 +1,8 @@
 //===- MSFBuilderTest.cpp  Tests manipulation of MSF stream metadata ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp
index 639536e..bc12721 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/MSF/MappedBlockStreamTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/MSF/MappedBlockStreamTest.cpp --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp
index 301b215..5f0695b 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/HashTableTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/PDB/HashTableTest.cpp ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -28,27 +27,35 @@
 
 namespace {
 
-class HashTableInternals : public HashTable<uint32_t> {
+struct IdentityHashTraits {
+  uint32_t hashLookupKey(uint32_t N) const { return N; }
+  uint32_t storageKeyToLookupKey(uint32_t N) const { return N; }
+  uint32_t lookupKeyToStorageKey(uint32_t N) { return N; }
+};
+
+template <class T = uint32_t>
+class HashTableInternals : public HashTable<T> {
 public:
-  using HashTable::Buckets;
-  using HashTable::Present;
-  using HashTable::Deleted;
+  using HashTable<T>::Buckets;
+  using HashTable<T>::Present;
+  using HashTable<T>::Deleted;
 };
 }
 
 TEST(HashTableTest, TestSimple) {
-  HashTableInternals Table;
+  HashTableInternals<> Table;
   EXPECT_EQ(0u, Table.size());
   EXPECT_GT(Table.capacity(), 0u);
 
-  Table.set_as(3u, 7);
+  IdentityHashTraits Traits;
+  Table.set_as(3u, 7, Traits);
   EXPECT_EQ(1u, Table.size());
-  ASSERT_NE(Table.end(), Table.find_as(3u));
-  EXPECT_EQ(7u, Table.get(3u));
+  ASSERT_NE(Table.end(), Table.find_as(3u, Traits));
+  EXPECT_EQ(7u, Table.get(3u, Traits));
 }
 
 TEST(HashTableTest, TestCollision) {
-  HashTableInternals Table;
+  HashTableInternals<> Table;
   EXPECT_EQ(0u, Table.size());
   EXPECT_GT(Table.capacity(), 0u);
 
@@ -58,33 +65,35 @@
   uint32_t N1 = Table.capacity() + 1;
   uint32_t N2 = 2 * N1;
 
-  Table.set_as(N1, 7);
-  Table.set_as(N2, 12);
+  IdentityHashTraits Traits;
+  Table.set_as(N1, 7, Traits);
+  Table.set_as(N2, 12, Traits);
   EXPECT_EQ(2u, Table.size());
-  ASSERT_NE(Table.end(), Table.find_as(N1));
-  ASSERT_NE(Table.end(), Table.find_as(N2));
+  ASSERT_NE(Table.end(), Table.find_as(N1, Traits));
+  ASSERT_NE(Table.end(), Table.find_as(N2, Traits));
 
-  EXPECT_EQ(7u, Table.get(N1));
-  EXPECT_EQ(12u, Table.get(N2));
+  EXPECT_EQ(7u, Table.get(N1, Traits));
+  EXPECT_EQ(12u, Table.get(N2, Traits));
 }
 
 TEST(HashTableTest, TestRemove) {
-  HashTableInternals Table;
+  HashTableInternals<> Table;
   EXPECT_EQ(0u, Table.size());
   EXPECT_GT(Table.capacity(), 0u);
 
-  Table.set_as(1u, 2);
-  Table.set_as(3u, 4);
+  IdentityHashTraits Traits;
+  Table.set_as(1u, 2, Traits);
+  Table.set_as(3u, 4, Traits);
   EXPECT_EQ(2u, Table.size());
-  ASSERT_NE(Table.end(), Table.find_as(1u));
-  ASSERT_NE(Table.end(), Table.find_as(3u));
+  ASSERT_NE(Table.end(), Table.find_as(1u, Traits));
+  ASSERT_NE(Table.end(), Table.find_as(3u, Traits));
 
-  EXPECT_EQ(2u, Table.get(1u));
-  EXPECT_EQ(4u, Table.get(3u));
+  EXPECT_EQ(2u, Table.get(1u, Traits));
+  EXPECT_EQ(4u, Table.get(3u, Traits));
 }
 
 TEST(HashTableTest, TestCollisionAfterMultipleProbes) {
-  HashTableInternals Table;
+  HashTableInternals<> Table;
   EXPECT_EQ(0u, Table.size());
   EXPECT_GT(Table.capacity(), 0u);
 
@@ -95,17 +104,18 @@
   uint32_t N2 = N1 + 1;
   uint32_t N3 = 2 * N1;
 
-  Table.set_as(N1, 7);
-  Table.set_as(N2, 11);
-  Table.set_as(N3, 13);
+  IdentityHashTraits Traits;
+  Table.set_as(N1, 7, Traits);
+  Table.set_as(N2, 11, Traits);
+  Table.set_as(N3, 13, Traits);
   EXPECT_EQ(3u, Table.size());
-  ASSERT_NE(Table.end(), Table.find_as(N1));
-  ASSERT_NE(Table.end(), Table.find_as(N2));
-  ASSERT_NE(Table.end(), Table.find_as(N3));
+  ASSERT_NE(Table.end(), Table.find_as(N1, Traits));
+  ASSERT_NE(Table.end(), Table.find_as(N2, Traits));
+  ASSERT_NE(Table.end(), Table.find_as(N3, Traits));
 
-  EXPECT_EQ(7u, Table.get(N1));
-  EXPECT_EQ(11u, Table.get(N2));
-  EXPECT_EQ(13u, Table.get(N3));
+  EXPECT_EQ(7u, Table.get(N1, Traits));
+  EXPECT_EQ(11u, Table.get(N2, Traits));
+  EXPECT_EQ(13u, Table.get(N3, Traits));
 }
 
 TEST(HashTableTest, Grow) {
@@ -113,24 +123,26 @@
   // guaranteed to trigger a grow.  Then verify that the size is the same, the
   // capacity is larger, and all the original items are still in the table.
 
-  HashTableInternals Table;
+  HashTableInternals<> Table;
+  IdentityHashTraits Traits;
   uint32_t OldCapacity = Table.capacity();
   for (uint32_t I = 0; I < OldCapacity; ++I) {
-    Table.set_as(OldCapacity + I * 2 + 1, I * 2 + 3);
+    Table.set_as(OldCapacity + I * 2 + 1, I * 2 + 3, Traits);
   }
   EXPECT_EQ(OldCapacity, Table.size());
   EXPECT_GT(Table.capacity(), OldCapacity);
   for (uint32_t I = 0; I < OldCapacity; ++I) {
-    ASSERT_NE(Table.end(), Table.find_as(OldCapacity + I * 2 + 1));
-    EXPECT_EQ(I * 2 + 3, Table.get(OldCapacity + I * 2 + 1));
+    ASSERT_NE(Table.end(), Table.find_as(OldCapacity + I * 2 + 1, Traits));
+    EXPECT_EQ(I * 2 + 3, Table.get(OldCapacity + I * 2 + 1, Traits));
   }
 }
 
 TEST(HashTableTest, Serialization) {
-  HashTableInternals Table;
+  HashTableInternals<> Table;
+  IdentityHashTraits Traits;
   uint32_t Cap = Table.capacity();
   for (uint32_t I = 0; I < Cap; ++I) {
-    Table.set_as(Cap + I * 2 + 1, I * 2 + 3);
+    Table.set_as(Cap + I * 2 + 1, I * 2 + 3, Traits);
   }
 
   std::vector<uint8_t> Buffer(Table.calculateSerializedLength());
@@ -140,7 +152,7 @@
   // We should have written precisely the number of bytes we calculated earlier.
   EXPECT_EQ(Buffer.size(), Writer.getOffset());
 
-  HashTableInternals Table2;
+  HashTableInternals<> Table2;
   BinaryStreamReader Reader(Stream);
   EXPECT_THAT_ERROR(Table2.load(Reader), Succeeded());
   // We should have read precisely the number of bytes we calculated earlier.
@@ -193,20 +205,19 @@
   } while (std::next_permutation(Streams.begin(), Streams.end()));
 }
 
-namespace {
 struct FooBar {
   uint32_t X;
   uint32_t Y;
+
+  bool operator==(const FooBar &RHS) const {
+    return X == RHS.X && Y == RHS.Y;
+  }
 };
 
-} // namespace
-
-namespace llvm {
-namespace pdb {
-template <> struct PdbHashTraits<FooBar> {
+struct FooBarHashTraits {
   std::vector<char> Buffer;
 
-  PdbHashTraits() { Buffer.push_back(0); }
+  FooBarHashTraits() { Buffer.push_back(0); }
 
   uint32_t hashLookupKey(StringRef S) const {
     return llvm::pdb::hashStringV1(S);
@@ -226,17 +237,16 @@
     return N;
   }
 };
-} // namespace pdb
-} // namespace llvm
 
 TEST(HashTableTest, NonTrivialValueType) {
-  HashTable<FooBar> Table;
+  HashTableInternals<FooBar> Table;
+  FooBarHashTraits Traits;
   uint32_t Cap = Table.capacity();
   for (uint32_t I = 0; I < Cap; ++I) {
     FooBar F;
     F.X = I;
     F.Y = I + 1;
-    Table.set_as(utostr(I), F);
+    Table.set_as(utostr(I), F, Traits);
   }
 
   std::vector<uint8_t> Buffer(Table.calculateSerializedLength());
@@ -246,7 +256,7 @@
   // We should have written precisely the number of bytes we calculated earlier.
   EXPECT_EQ(Buffer.size(), Writer.getOffset());
 
-  HashTable<FooBar> Table2;
+  HashTableInternals<FooBar> Table2;
   BinaryStreamReader Reader(Stream);
   EXPECT_THAT_ERROR(Table2.load(Reader), Succeeded());
   // We should have read precisely the number of bytes we calculated earlier.
@@ -254,7 +264,7 @@
 
   EXPECT_EQ(Table.size(), Table2.size());
   EXPECT_EQ(Table.capacity(), Table2.capacity());
-  // EXPECT_EQ(Table.Buckets, Table2.Buckets);
-  // EXPECT_EQ(Table.Present, Table2.Present);
-  // EXPECT_EQ(Table.Deleted, Table2.Deleted);
+  EXPECT_EQ(Table.Buckets, Table2.Buckets);
+  EXPECT_EQ(Table.Present, Table2.Present);
+  EXPECT_EQ(Table.Deleted, Table2.Deleted);
 }
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp
index 15afea6..91c7db4 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/NativeSymbolReuseTest.cpp
@@ -1,9 +1,8 @@
 //===- NativeSymbolReuseTest.cpp ------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp
index 007ea90..766f54d 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/PDBApiTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/DebugInfo/PDB/PDBApiTest.cpp -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp b/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
index bf08ab2..2f7c061 100644
--- a/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/DebugInfo/PDB/StringTableBuilderTest.cpp
@@ -1,9 +1,8 @@
 //===- StringTableBuilderTest.cpp -----------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -20,11 +19,7 @@
 using namespace llvm::pdb;
 using namespace llvm::support;
 
-namespace {
-class StringTableBuilderTest : public ::testing::Test {};
-}
-
-TEST_F(StringTableBuilderTest, Simple) {
+TEST(StringTableBuilderTest, Simple) {
   // Create /names table contents.
   PDBStringTableBuilder Builder;
 
@@ -79,3 +74,21 @@
   EXPECT_THAT_EXPECTED(Table.getIDForString("bazz"), HasValue(BazzID));
   EXPECT_THAT_EXPECTED(Table.getIDForString("barr"), HasValue(BarrID));
 }
+
+TEST(StringTableHashTraitsTest, Simple) {
+  PDBStringTableBuilder Builder;
+
+  // Create more than 64kiB of dummy entries.
+  for (int i = 0; i < 320; ++i) {
+    std::string aaaaa = std::string(220, 'a') + std::to_string(i);
+    Builder.insert(aaaaa);
+  }
+
+  std::string S = "foo.natvis";
+  uint32_t Pos = Builder.insert(S);
+
+  EXPECT_GT(Pos, 0xFFFFu);
+
+  StringTableHashTraits Traits(Builder);
+  EXPECT_LE(Traits.hashLookupKey(S), 0xFFFFu);
+}
diff --git a/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt b/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt
index 954f3d0..c6291bb 100644
--- a/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Demangle/CMakeLists.txt
@@ -4,6 +4,7 @@
 )
 
 add_llvm_unittest(DemangleTests
+  DemangleTest.cpp
   ItaniumDemangleTest.cpp
   PartialDemangleTest.cpp
 )
diff --git a/src/llvm-project/llvm/unittests/Demangle/DemangleTest.cpp b/src/llvm-project/llvm/unittests/Demangle/DemangleTest.cpp
new file mode 100644
index 0000000..cb70a72
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Demangle/DemangleTest.cpp
@@ -0,0 +1,24 @@
+//===-- DemangleTest.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Demangle/Demangle.h"
+#include "gmock/gmock.h"
+
+using namespace llvm;
+
+TEST(Demangle, demangleTest) {
+  EXPECT_EQ(demangle("_"), "_");
+  EXPECT_EQ(demangle("_Z3fooi"), "foo(int)");
+  EXPECT_EQ(demangle("__Z3fooi"), "foo(int)");
+  EXPECT_EQ(demangle("___Z3fooi_block_invoke"),
+            "invocation function for block in foo(int)");
+  EXPECT_EQ(demangle("____Z3fooi_block_invoke"),
+            "invocation function for block in foo(int)");
+  EXPECT_EQ(demangle("?foo@@YAXH@Z"), "void __cdecl foo(int)");
+  EXPECT_EQ(demangle("foo"), "foo");
+}
diff --git a/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp b/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp
index abb690c..11bb784 100644
--- a/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp
+++ b/src/llvm-project/llvm/unittests/Demangle/ItaniumDemangleTest.cpp
@@ -1,9 +1,8 @@
 //===------------------ ItaniumDemangleTest.cpp ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp b/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp
index 8bb4a3a..0379d83 100644
--- a/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp
+++ b/src/llvm-project/llvm/unittests/Demangle/PartialDemangleTest.cpp
@@ -1,9 +1,8 @@
 //===----------------------- PartialDemangleTest.cpp ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt b/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt
index 302de99..1bf2105 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/CMakeLists.txt
@@ -12,6 +12,7 @@
   ExecutionEngineTest.cpp
   )
 
+add_subdirectory(JITLink)
 add_subdirectory(Orc)
 
 # Include MCJIT tests only if native arch is a built JIT target.
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp
index ec5fab6..77b1085 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -1,9 +1,8 @@
 //===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt
new file mode 100644
index 0000000..9f9ffbb
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/CMakeLists.txt
@@ -0,0 +1,18 @@
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  JITLink
+  MC
+  MCDisassembler
+  MCParser
+  Object
+  RuntimeDyld
+  Support
+  Target
+  )
+
+add_llvm_unittest(JITLinkTests
+    JITLinkTestCommon.cpp
+    MachO_x86_64_Tests.cpp
+  )
+
+target_link_libraries(JITLinkTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.cpp
new file mode 100644
index 0000000..b0c6d5b
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.cpp
@@ -0,0 +1,251 @@
+//===------- JITLinkTestCommon.cpp - Common code for JITLink tests --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITLinkTestCommon.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCParser/MCTargetAsmParser.h"
+#include "llvm/Support/TargetSelect.h"
+
+using namespace llvm::jitlink;
+namespace llvm {
+
+Expected<std::unique_ptr<JITLinkTestCommon::TestResources>>
+JITLinkTestCommon::TestResources::Create(StringRef AsmSrc, StringRef TripleStr,
+                                         bool PIC, bool LargeCodeModel,
+                                         MCTargetOptions Options) {
+  Error Err = Error::success();
+  auto R = std::unique_ptr<TestResources>(new TestResources(
+      AsmSrc, TripleStr, PIC, LargeCodeModel, std::move(Options), Err));
+  if (Err)
+    return std::move(Err);
+  return std::move(R);
+}
+
+MemoryBufferRef
+JITLinkTestCommon::TestResources::getTestObjectBufferRef() const {
+  return MemoryBufferRef(StringRef(ObjBuffer.data(), ObjBuffer.size()),
+                         "Test object");
+}
+
+JITLinkTestCommon::TestResources::TestResources(StringRef AsmSrc,
+                                                StringRef TripleStr, bool PIC,
+                                                bool LargeCodeModel,
+                                                MCTargetOptions Options,
+                                                Error &Err)
+    : ObjStream(ObjBuffer), Options(std::move(Options)) {
+  ErrorAsOutParameter _(&Err);
+  Triple TT(Triple::normalize(TripleStr));
+  if (auto Err2 = initializeTripleSpecifics(TT)) {
+    Err = std::move(Err2);
+    return;
+  }
+  initializeTestSpecifics(AsmSrc, TT, PIC, LargeCodeModel);
+}
+
+Error JITLinkTestCommon::TestResources::initializeTripleSpecifics(Triple &TT) {
+  std::string ErrorMsg;
+  TheTarget = TargetRegistry::lookupTarget("", TT, ErrorMsg);
+
+  if (!TheTarget)
+    return make_error<StringError>(ErrorMsg, inconvertibleErrorCode());
+
+  MRI.reset(TheTarget->createMCRegInfo(TT.getTriple()));
+  if (!MRI)
+    report_fatal_error("Could not build MCRegisterInfo for triple");
+
+  MAI.reset(TheTarget->createMCAsmInfo(*MRI, TT.getTriple()));
+  if (!MAI)
+    report_fatal_error("Could not build MCAsmInfo for triple");
+
+  MCII.reset(TheTarget->createMCInstrInfo());
+  if (!MCII)
+    report_fatal_error("Could not build MCInstrInfo for triple");
+
+  STI.reset(TheTarget->createMCSubtargetInfo(TT.getTriple(), "", ""));
+  if (!STI)
+    report_fatal_error("Could not build MCSubtargetInfo for triple");
+
+  DisCtx = llvm::make_unique<MCContext>(MAI.get(), MRI.get(), nullptr);
+  Dis.reset(TheTarget->createMCDisassembler(*STI, *DisCtx));
+
+  if (!Dis)
+    report_fatal_error("Could not build MCDisassembler");
+
+  return Error::success();
+}
+
+void JITLinkTestCommon::TestResources::initializeTestSpecifics(
+    StringRef AsmSrc, const Triple &TT, bool PIC, bool LargeCodeModel) {
+  SrcMgr.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(AsmSrc), SMLoc());
+  AsCtx = llvm::make_unique<MCContext>(MAI.get(), MRI.get(), &MOFI, &SrcMgr);
+  MOFI.InitMCObjectFileInfo(TT, PIC, *AsCtx, LargeCodeModel);
+
+  std::unique_ptr<MCCodeEmitter> CE(
+      TheTarget->createMCCodeEmitter(*MCII, *MRI, *AsCtx));
+  if (!CE)
+    report_fatal_error("Could not build MCCodeEmitter");
+
+  std::unique_ptr<MCAsmBackend> MAB(
+      TheTarget->createMCAsmBackend(*STI, *MRI, Options));
+  if (!MAB)
+    report_fatal_error("Could not build MCAsmBackend for test");
+
+  std::unique_ptr<MCObjectWriter> MOW(MAB->createObjectWriter(ObjStream));
+
+  MOS.reset(TheTarget->createMCObjectStreamer(
+      TT, *AsCtx, std::move(MAB), std::move(MOW), std::move(CE), *STI,
+      Options.MCRelaxAll, Options.MCIncrementalLinkerCompatible, false));
+
+  std::unique_ptr<MCAsmParser> MAP(
+      createMCAsmParser(SrcMgr, *AsCtx, *MOS, *MAI));
+  std::unique_ptr<MCTargetAsmParser> TAP(
+      TheTarget->createMCAsmParser(*STI, *MAP, *MCII, Options));
+
+  if (!TAP)
+    report_fatal_error("Could not build MCTargetAsmParser for test");
+
+  MAP->setTargetParser(*TAP);
+
+  if (MAP->Run(false))
+    report_fatal_error("Failed to parse test case");
+}
+
+JITLinkTestCommon::TestJITLinkContext::TestJITLinkContext(
+    TestResources &TR, TestCaseFunction TestCase)
+    : TR(TR), TestCase(std::move(TestCase)) {}
+
+JITLinkTestCommon::TestJITLinkContext &
+JITLinkTestCommon::TestJITLinkContext::setMemoryManager(
+    std::unique_ptr<JITLinkMemoryManager> MM) {
+  assert(!MemMgr && "Memory manager already set");
+  MemMgr = std::move(MM);
+  return *this;
+}
+
+JITLinkMemoryManager &
+JITLinkTestCommon::TestJITLinkContext::getMemoryManager() {
+  if (!MemMgr)
+    MemMgr = llvm::make_unique<InProcessMemoryManager>();
+  return *MemMgr;
+}
+
+MemoryBufferRef JITLinkTestCommon::TestJITLinkContext::getObjectBuffer() const {
+  return TR.getTestObjectBufferRef();
+}
+
+void JITLinkTestCommon::TestJITLinkContext::notifyFailed(Error Err) {
+  ADD_FAILURE() << "Unexpected failure: " << toString(std::move(Err));
+}
+
+void JITLinkTestCommon::TestJITLinkContext::lookup(
+    const DenseSet<StringRef> &Symbols,
+    JITLinkAsyncLookupContinuation LookupContinuation) {
+  jitlink::AsyncLookupResult LookupResult;
+  DenseSet<StringRef> MissingSymbols;
+  for (const auto &Symbol : Symbols) {
+    auto I = Externals.find(Symbol);
+    if (I != Externals.end())
+      LookupResult[Symbol] = I->second;
+    else
+      MissingSymbols.insert(Symbol);
+  }
+
+  if (MissingSymbols.empty())
+    LookupContinuation(std::move(LookupResult));
+  else {
+    std::string ErrMsg;
+    {
+      raw_string_ostream ErrMsgStream(ErrMsg);
+      ErrMsgStream << "Failed to resolve external symbols: [";
+      for (auto &Sym : MissingSymbols)
+        ErrMsgStream << " " << Sym;
+      ErrMsgStream << " ]\n";
+    }
+    LookupContinuation(
+        make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()));
+  }
+}
+
+void JITLinkTestCommon::TestJITLinkContext::notifyResolved(AtomGraph &G) {
+  if (NotifyResolved)
+    NotifyResolved(G);
+}
+
+void JITLinkTestCommon::TestJITLinkContext::notifyFinalized(
+    std::unique_ptr<JITLinkMemoryManager::Allocation> A) {
+  if (NotifyFinalized)
+    NotifyFinalized(std::move(A));
+}
+
+Error JITLinkTestCommon::TestJITLinkContext::modifyPassConfig(
+    const Triple &TT, PassConfiguration &Config) {
+  if (TestCase)
+    Config.PostFixupPasses.push_back([&](AtomGraph &G) -> Error {
+      TestCase(G);
+      return Error::success();
+    });
+  return Error::success();
+}
+
+JITLinkTestCommon::JITLinkTestCommon() { initializeLLVMTargets(); }
+
+Expected<std::pair<MCInst, size_t>>
+JITLinkTestCommon::disassemble(const MCDisassembler &Dis,
+                               jitlink::DefinedAtom &Atom, size_t Offset) {
+  ArrayRef<uint8_t> InstBuffer(
+      reinterpret_cast<const uint8_t *>(Atom.getContent().data()) + Offset,
+      Atom.getContent().size() - Offset);
+
+  MCInst Inst;
+  uint64_t InstSize;
+  auto Status =
+      Dis.getInstruction(Inst, InstSize, InstBuffer, 0, nulls(), nulls());
+
+  if (Status != MCDisassembler::Success)
+    return make_error<StringError>("Could not disassemble instruction",
+                                   inconvertibleErrorCode());
+
+  return std::make_pair(Inst, InstSize);
+}
+
+Expected<int64_t>
+JITLinkTestCommon::decodeImmediateOperand(const MCDisassembler &Dis,
+                                          jitlink::DefinedAtom &Atom,
+                                          size_t OpIdx, size_t Offset) {
+  auto InstAndSize = disassemble(Dis, Atom, Offset);
+  if (!InstAndSize)
+    return InstAndSize.takeError();
+
+  if (OpIdx >= InstAndSize->first.getNumOperands())
+    return make_error<StringError>("Invalid operand index",
+                                   inconvertibleErrorCode());
+
+  auto &Op = InstAndSize->first.getOperand(OpIdx);
+
+  if (!Op.isImm())
+    return make_error<StringError>("Operand at index is not immediate",
+                                   inconvertibleErrorCode());
+
+  return Op.getImm();
+}
+
+bool JITLinkTestCommon::AreTargetsInitialized = false;
+
+void JITLinkTestCommon::initializeLLVMTargets() {
+  if (!AreTargetsInitialized) {
+    InitializeAllTargets();
+    InitializeAllTargetMCs();
+    InitializeAllAsmParsers();
+    InitializeAllAsmPrinters();
+    InitializeAllDisassemblers();
+    AreTargetsInitialized = true;
+  }
+}
+
+} // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.h b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.h
new file mode 100644
index 0000000..8e1273e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/JITLinkTestCommon.h
@@ -0,0 +1,205 @@
+//===---- JITLinkTestCommon.h - Utilities for Orc Unit Tests ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for JITLink unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
+#define LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKTESTCOMMON_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+class JITLinkTestCommon {
+public:
+
+  class TestResources {
+  public:
+    static Expected<std::unique_ptr<TestResources>>
+    Create(StringRef AsmSrc, StringRef TripleStr, bool PIC, bool LargeCodeModel,
+           MCTargetOptions Options);
+
+    MemoryBufferRef getTestObjectBufferRef() const;
+
+    const MCDisassembler &getDisassembler() const { return *Dis; }
+
+  private:
+    TestResources(StringRef AsmSrc, StringRef TripleStr, bool PIC,
+                  bool LargeCodeModel, MCTargetOptions Options, Error &Err);
+
+    Error initializeTripleSpecifics(Triple &TT);
+    void initializeTestSpecifics(StringRef AsmSource, const Triple &TT,
+                                 bool PIC, bool LargeCodeModel);
+
+    const Target *TheTarget = nullptr;
+    SourceMgr SrcMgr;
+    SmallVector<char, 0> ObjBuffer;
+    raw_svector_ostream ObjStream;
+
+    MCTargetOptions Options;
+    std::unique_ptr<MCRegisterInfo> MRI;
+    std::unique_ptr<MCAsmInfo> MAI;
+    std::unique_ptr<MCInstrInfo> MCII;
+    std::unique_ptr<MCSubtargetInfo> STI;
+
+    MCObjectFileInfo MOFI;
+    std::unique_ptr<MCContext> AsCtx;
+    std::unique_ptr<MCStreamer> MOS;
+
+    std::unique_ptr<MCContext> DisCtx;
+    std::unique_ptr<const MCDisassembler> Dis;
+  };
+
+  class TestJITLinkContext : public jitlink::JITLinkContext {
+  public:
+    using TestCaseFunction = std::function<void(jitlink::AtomGraph &)>;
+
+    using NotifyResolvedFunction = std::function<void(jitlink::AtomGraph &G)>;
+
+    using NotifyFinalizedFunction = std::function<void(
+        std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>)>;
+
+    TestJITLinkContext(TestResources &TR, TestCaseFunction TestCase);
+
+    StringMap<JITEvaluatedSymbol> &externals() { return Externals; }
+
+    TestJITLinkContext &
+    setNotifyResolved(NotifyResolvedFunction NotifyResolved);
+
+    TestJITLinkContext &
+    setNotifyFinalized(NotifyFinalizedFunction NotifyFinalized);
+
+    TestJITLinkContext &
+    setMemoryManager(std::unique_ptr<jitlink::JITLinkMemoryManager> MM);
+
+    jitlink::JITLinkMemoryManager &getMemoryManager() override;
+
+    MemoryBufferRef getObjectBuffer() const override;
+
+    void notifyFailed(Error Err) override;
+
+    void
+    lookup(const DenseSet<StringRef> &Symbols,
+           jitlink::JITLinkAsyncLookupContinuation LookupContinuation) override;
+
+    void notifyResolved(jitlink::AtomGraph &G) override;
+
+    void notifyFinalized(
+        std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation> A) override;
+
+    Error modifyPassConfig(const Triple &TT,
+                           jitlink::PassConfiguration &Config) override;
+
+  private:
+    TestResources &TR;
+    TestCaseFunction TestCase;
+    NotifyResolvedFunction NotifyResolved;
+    NotifyFinalizedFunction NotifyFinalized;
+    std::unique_ptr<MemoryBuffer> ObjBuffer;
+    std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr;
+    StringMap<JITEvaluatedSymbol> Externals;
+  };
+
+  JITLinkTestCommon();
+
+  /// Get TestResources for this target/test.
+  ///
+  /// If this method fails it is likely because the target is not supported in
+  /// this build. The test should bail out without failing (possibly logging a
+  /// diagnostic).
+  Expected<std::unique_ptr<TestResources>>
+  getTestResources(StringRef AsmSrc, StringRef Triple, bool PIC,
+                   bool LargeCodeModel, MCTargetOptions Options) const {
+    return TestResources::Create(AsmSrc, Triple, PIC, LargeCodeModel,
+                                 std::move(Options));
+  }
+
+  template <typename T>
+  static Expected<T> readInt(jitlink::AtomGraph &G, jitlink::DefinedAtom &A,
+                             size_t Offset = 0) {
+    if (Offset + sizeof(T) > A.getContent().size())
+      return make_error<StringError>("Reading past end of atom content",
+                                     inconvertibleErrorCode());
+    return support::endian::read<T, 1>(A.getContent().data() + Offset,
+                                       G.getEndianness());
+  }
+
+  template <typename T>
+  static Expected<T> readInt(jitlink::AtomGraph &G, StringRef AtomName,
+                             size_t Offset = 0) {
+    auto DA = G.findDefinedAtomByName(AtomName);
+    if (!DA)
+      return DA.takeError();
+    return readInt<T>(G, *DA);
+  }
+
+  static Expected<std::pair<MCInst, size_t>>
+  disassemble(const MCDisassembler &Dis, jitlink::DefinedAtom &Atom,
+              size_t Offset = 0);
+
+  static Expected<int64_t> decodeImmediateOperand(const MCDisassembler &Dis,
+                                                  jitlink::DefinedAtom &Atom,
+                                                  size_t OpIdx,
+                                                  size_t Offset = 0);
+
+  static jitlink::Atom &atom(jitlink::AtomGraph &G, StringRef Name) {
+    return G.getAtomByName(Name);
+  }
+
+  static jitlink::DefinedAtom &definedAtom(jitlink::AtomGraph &G,
+                                           StringRef Name) {
+    return G.getDefinedAtomByName(Name);
+  }
+
+  static JITTargetAddress atomAddr(jitlink::AtomGraph &G, StringRef Name) {
+    return atom(G, Name).getAddress();
+  }
+
+  template <typename PredT>
+  static size_t countEdgesMatching(jitlink::DefinedAtom &DA,
+                                   const PredT &Pred) {
+    return std::count_if(DA.edges().begin(), DA.edges().end(), Pred);
+  }
+
+  template <typename PredT>
+  static size_t countEdgesMatching(jitlink::AtomGraph &G, StringRef Name,
+                                   const PredT &Pred) {
+    return countEdgesMatching(definedAtom(G, Name), Pred);
+  }
+
+private:
+
+  static bool AreTargetsInitialized;
+  void initializeLLVMTargets();
+
+  DenseMap<StringRef, JITEvaluatedSymbol> Externals;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/MachO_x86_64_Tests.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/MachO_x86_64_Tests.cpp
new file mode 100644
index 0000000..98c5d44
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/JITLink/MachO_x86_64_Tests.cpp
@@ -0,0 +1,229 @@
+//===--------- MachO_x86_64.cpp - Tests for JITLink MachO/x86-64 ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITLinkTestCommon.h"
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ExecutionEngine/JITLink/MachO_x86_64.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::jitlink;
+using namespace llvm::jitlink::MachO_x86_64_Edges;
+
+namespace {
+
+class JITLinkTest_MachO_x86_64 : public JITLinkTestCommon,
+                                 public testing::Test {
+public:
+  using BasicVerifyGraphFunction =
+      std::function<void(AtomGraph &, const MCDisassembler &)>;
+
+  void runBasicVerifyGraphTest(StringRef AsmSrc, StringRef Triple,
+                               StringMap<JITEvaluatedSymbol> Externals,
+                               bool PIC, bool LargeCodeModel,
+                               MCTargetOptions Options,
+                               BasicVerifyGraphFunction RunGraphTest) {
+    auto TR = getTestResources(AsmSrc, Triple, PIC, LargeCodeModel,
+                               std::move(Options));
+    if (!TR) {
+      dbgs() << "Skipping JITLInk unit test: " << toString(TR.takeError())
+             << "\n";
+      return;
+    }
+
+    auto JTCtx = llvm::make_unique<TestJITLinkContext>(
+        **TR, [&](AtomGraph &G) { RunGraphTest(G, (*TR)->getDisassembler()); });
+
+    JTCtx->externals() = std::move(Externals);
+
+    jitLink_MachO_x86_64(std::move(JTCtx));
+  }
+
+protected:
+  static void verifyIsPointerTo(AtomGraph &G, DefinedAtom &A, Atom &Target) {
+    EXPECT_EQ(A.edges_size(), 1U) << "Incorrect number of edges for pointer";
+    if (A.edges_size() != 1U)
+      return;
+    auto &E = *A.edges().begin();
+    EXPECT_EQ(E.getKind(), Pointer64)
+        << "Expected pointer to have a pointer64 relocation";
+    EXPECT_EQ(&E.getTarget(), &Target) << "Expected edge to point at target";
+    EXPECT_THAT_EXPECTED(readInt<uint64_t>(G, A), HasValue(Target.getAddress()))
+        << "Pointer does not point to target";
+  }
+
+  static void verifyGOTLoad(AtomGraph &G, DefinedAtom &A, Edge &E,
+                            Atom &Target) {
+    EXPECT_EQ(E.getAddend(), 0U) << "Expected GOT load to have a zero addend";
+    EXPECT_TRUE(E.getTarget().isDefined())
+        << "GOT entry should be a defined atom";
+    if (!E.getTarget().isDefined())
+      return;
+
+    verifyIsPointerTo(G, static_cast<DefinedAtom &>(E.getTarget()), Target);
+  }
+
+  static void verifyCall(const MCDisassembler &Dis, AtomGraph &G,
+                         DefinedAtom &Caller, Edge &E, Atom &Callee) {
+    EXPECT_EQ(E.getKind(), Branch32) << "Edge is not a Branch32";
+    EXPECT_EQ(E.getAddend(), 0U) << "Expected no addend on stub call";
+    EXPECT_EQ(&E.getTarget(), &Callee)
+        << "Edge does not point at expected callee";
+
+    JITTargetAddress FixupAddress = Caller.getAddress() + E.getOffset();
+    uint64_t PCRelDelta = Callee.getAddress() - (FixupAddress + 4);
+
+    EXPECT_THAT_EXPECTED(
+        decodeImmediateOperand(Dis, Caller, 0, E.getOffset() - 1),
+        HasValue(PCRelDelta));
+  }
+
+  static void verifyIndirectCall(const MCDisassembler &Dis, AtomGraph &G,
+                                 DefinedAtom &Caller, Edge &E, Atom &Callee) {
+    EXPECT_EQ(E.getKind(), PCRel32) << "Edge is not a PCRel32";
+    EXPECT_EQ(E.getAddend(), 0) << "Expected no addend on stub cal";
+    EXPECT_TRUE(E.getTarget().isDefined()) << "Target is not a defined atom";
+    if (!E.getTarget().isDefined())
+      return;
+    verifyIsPointerTo(G, static_cast<DefinedAtom &>(E.getTarget()), Callee);
+
+    JITTargetAddress FixupAddress = Caller.getAddress() + E.getOffset();
+    uint64_t PCRelDelta = E.getTarget().getAddress() - (FixupAddress + 4);
+
+    EXPECT_THAT_EXPECTED(
+        decodeImmediateOperand(Dis, Caller, 3, E.getOffset() - 2),
+        HasValue(PCRelDelta));
+  }
+
+  static void verifyCallViaStub(const MCDisassembler &Dis, AtomGraph &G,
+                                DefinedAtom &Caller, Edge &E, Atom &Callee) {
+    verifyCall(Dis, G, Caller, E, E.getTarget());
+
+    if (!E.getTarget().isDefined()) {
+      ADD_FAILURE() << "Edge target is not a stub";
+      return;
+    }
+
+    auto &StubAtom = static_cast<DefinedAtom &>(E.getTarget());
+    EXPECT_EQ(StubAtom.edges_size(), 1U)
+        << "Expected one edge from stub to target";
+
+    auto &StubEdge = *StubAtom.edges().begin();
+
+    verifyIndirectCall(Dis, G, static_cast<DefinedAtom &>(StubAtom), StubEdge,
+                       Callee);
+  }
+};
+
+} // end anonymous namespace
+
+// Test each operation on LegacyObjectTransformLayer.
+TEST_F(JITLinkTest_MachO_x86_64, BasicRelocations) {
+  runBasicVerifyGraphTest(
+      R"(
+            .section        __TEXT,__text,regular,pure_instructions
+            .build_version macos, 10, 14
+            .globl  _bar
+            .p2align        4, 0x90
+    _bar:
+            callq    _baz
+
+            .globl  _foo
+            .p2align        4, 0x90
+    _foo:
+            callq   _bar
+    _foo.1:
+            movq    _y@GOTPCREL(%rip), %rcx
+    _foo.2:
+            movq    _p(%rip), %rdx
+
+            .section        __DATA,__data
+            .globl  _x
+            .p2align        2
+    _x:
+            .long   42
+
+            .globl  _p
+            .p2align        3
+    _p:
+            .quad   _x
+
+    .subsections_via_symbols)",
+      "x86_64-apple-macosx10.14",
+      {{"_y", JITEvaluatedSymbol(0xdeadbeef, JITSymbolFlags::Exported)},
+       {"_baz", JITEvaluatedSymbol(0xcafef00d, JITSymbolFlags::Exported)}},
+      true, false, MCTargetOptions(),
+      [](AtomGraph &G, const MCDisassembler &Dis) {
+        // Name the atoms in the asm above.
+        auto &Baz = atom(G, "_baz");
+        auto &Y = atom(G, "_y");
+
+        auto &Bar = definedAtom(G, "_bar");
+        auto &Foo = definedAtom(G, "_foo");
+        auto &Foo_1 = definedAtom(G, "_foo.1");
+        auto &Foo_2 = definedAtom(G, "_foo.2");
+        auto &X = definedAtom(G, "_x");
+        auto &P = definedAtom(G, "_p");
+
+        // Check unsigned reloc for _p
+        {
+          EXPECT_EQ(P.edges_size(), 1U) << "Unexpected number of relocations";
+          EXPECT_EQ(P.edges().begin()->getKind(), Pointer64)
+              << "Unexpected edge kind for _p";
+          EXPECT_THAT_EXPECTED(readInt<uint64_t>(G, P),
+                               HasValue(X.getAddress()))
+              << "Unsigned relocation did not apply correctly";
+        }
+
+        // Check that _bar is a call-via-stub to _baz.
+        // This will check that the call goes to a stub, that the stub is an
+        // indirect call, and that the pointer for the indirect call points to
+        // baz.
+        {
+          EXPECT_EQ(Bar.edges_size(), 1U)
+              << "Incorrect number of edges for bar";
+          EXPECT_EQ(Bar.edges().begin()->getKind(), Branch32)
+              << "Unexpected edge kind for _bar";
+          verifyCallViaStub(Dis, G, Bar, *Bar.edges().begin(), Baz);
+        }
+
+        // Check that _foo is a direct call to _bar.
+        {
+          EXPECT_EQ(Foo.edges_size(), 1U)
+              << "Incorrect number of edges for foo";
+          EXPECT_EQ(Foo.edges().begin()->getKind(), Branch32);
+          verifyCall(Dis, G, Foo, *Foo.edges().begin(), Bar);
+        }
+
+        // Check .got load in _foo.1
+        {
+          EXPECT_EQ(Foo_1.edges_size(), 1U)
+              << "Incorrect number of edges for foo_1";
+          EXPECT_EQ(Foo_1.edges().begin()->getKind(), PCRel32);
+          verifyGOTLoad(G, Foo_1, *Foo_1.edges().begin(), Y);
+        }
+
+        // Check PCRel ref to _p in _foo.2
+        {
+          EXPECT_EQ(Foo_2.edges_size(), 1U)
+              << "Incorrect number of edges for foo_2";
+          EXPECT_EQ(Foo_2.edges().begin()->getKind(), PCRel32);
+
+          JITTargetAddress FixupAddress =
+              Foo_2.getAddress() + Foo_2.edges().begin()->getOffset();
+          uint64_t PCRelDelta = P.getAddress() - (FixupAddress + 4);
+
+          EXPECT_THAT_EXPECTED(decodeImmediateOperand(Dis, Foo_2, 4, 0),
+                               HasValue(PCRelDelta))
+              << "PCRel load does not reference expected target";
+        }
+      });
+}
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
index bc1ebc5..52b3b76 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -1,9 +1,8 @@
 //===- MCJITTest.cpp - Unit tests for the MCJIT -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
index 0582c92..7a756a7 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
@@ -1,9 +1,8 @@
 //===- MCJITMemoryManagerTest.cpp - Unit tests for the JIT memory manager -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
index 856ae45..710ce6d 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
@@ -1,9 +1,8 @@
 //===- MCJITMultipeModuleTest.cpp - Unit tests for the MCJIT ----*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -212,10 +211,10 @@
   GVB = insertGlobalInt32(B.get(), "GVB", initialNum);
   FA = startFunction(A.get(),
                      FunctionType::get(Builder.getInt32Ty(), {}, false), "FA");
-  endFunctionWithRet(FA, Builder.CreateLoad(GVA));
+  endFunctionWithRet(FA, Builder.CreateLoad(Builder.getInt32Ty(), GVA));
   FB = startFunction(B.get(),
                      FunctionType::get(Builder.getInt32Ty(), {}, false), "FB");
-  endFunctionWithRet(FB, Builder.CreateLoad(GVB));
+  endFunctionWithRet(FB, Builder.CreateLoad(Builder.getInt32Ty(), GVB));
 
   GVC = insertGlobalInt32(B.get(), "GVC", initialNum);
   GVC->setLinkage(GlobalValue::InternalLinkage);
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
index 2e3d2b6..4ec2e1a 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -1,9 +1,8 @@
 //===- MCJITObjectCacheTest.cpp - Unit tests for MCJIT object caching -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
index 8972fb6..1409907 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
@@ -1,9 +1,8 @@
 //===- MCJITTest.cpp - Unit tests for the MCJIT -----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -102,7 +101,7 @@
   Function *ReturnGlobal =
       startFunction(M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
                     "ReturnGlobal");
-  Value *ReadGlobal = Builder.CreateLoad(GV);
+  Value *ReadGlobal = Builder.CreateLoad(Builder.getInt32Ty(), GV);
   endFunctionWithRet(ReturnGlobal, ReadGlobal);
 
   createJIT(std::move(M));
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
index d3ebb95..0f55443 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
@@ -1,9 +1,8 @@
 //===- MCJITTestBase.h - Common base class for MCJIT Unit tests  ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index 50a57f1..e0c4b07 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -1,9 +1,8 @@
 //===- MCJITTestBase.h - Common base class for MCJIT Unit tests -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
index 019437d..945c992 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -4,6 +4,7 @@
   ExecutionEngine
   Object
   OrcJIT
+  Passes
   RuntimeDyld
   Support
   native
@@ -30,4 +31,6 @@
   ThreadSafeModuleTest.cpp
   )
 
-target_link_libraries(OrcJITTests PRIVATE ${ORC_JIT_TEST_LIBS})
+target_link_libraries(OrcJITTests PRIVATE
+                        LLVMTestingSupport
+                        ${ORC_JIT_TEST_LIBS})
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
index 22be76a..fb55c4b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
@@ -1,9 +1,8 @@
 //===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -11,6 +10,7 @@
 #include "llvm/Config/llvm-config.h"
 #include "llvm/ExecutionEngine/Orc/Core.h"
 #include "llvm/ExecutionEngine/Orc/OrcError.h"
+#include "llvm/Testing/Support/Error.h"
 
 #include <set>
 #include <thread>
@@ -23,21 +23,16 @@
 namespace {
 
 TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) {
-  bool OnResolutionRun = false;
-  bool OnReadyRun = false;
+  bool OnCompletionRun = false;
 
-  auto OnResolution = [&](Expected<SymbolMap> Result) {
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
     EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
     auto &Resolved = *Result;
     auto I = Resolved.find(Foo);
     EXPECT_NE(I, Resolved.end()) << "Could not find symbol definition";
     EXPECT_EQ(I->second.getAddress(), FooAddr)
         << "Resolution returned incorrect result";
-    OnResolutionRun = true;
-  };
-  auto OnReady = [&](Error Err) {
-    cantFail(std::move(Err));
-    OnReadyRun = true;
+    OnCompletionRun = true;
   };
 
   std::shared_ptr<MaterializationResponsibility> FooMR;
@@ -48,65 +43,51 @@
         FooMR = std::make_shared<MaterializationResponsibility>(std::move(R));
       })));
 
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolution, OnReady,
-            NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+            OnCompletion, NoDependenciesToRegister);
 
-  EXPECT_FALSE(OnResolutionRun) << "Should not have been resolved yet";
-  EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
+  EXPECT_FALSE(OnCompletionRun) << "Should not have been resolved yet";
 
-  FooMR->resolve({{Foo, FooSym}});
+  FooMR->notifyResolved({{Foo, FooSym}});
 
-  EXPECT_TRUE(OnResolutionRun) << "Should have been resolved";
-  EXPECT_FALSE(OnReadyRun) << "Should not have been marked ready yet";
+  EXPECT_FALSE(OnCompletionRun) << "Should not be ready yet";
 
-  FooMR->emit();
+  FooMR->notifyEmitted();
 
-  EXPECT_TRUE(OnReadyRun) << "Should have been marked ready";
+  EXPECT_TRUE(OnCompletionRun) << "Should have been marked ready";
 }
 
 TEST_F(CoreAPIsStandardTest, ExecutionSessionFailQuery) {
-  bool OnResolutionRun = false;
-  bool OnReadyRun = false;
+  bool OnCompletionRun = false;
 
-  auto OnResolution = [&](Expected<SymbolMap> Result) {
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
     EXPECT_FALSE(!!Result) << "Resolution unexpectedly returned success";
     auto Msg = toString(Result.takeError());
     EXPECT_EQ(Msg, "xyz") << "Resolution returned incorrect result";
-    OnResolutionRun = true;
-  };
-  auto OnReady = [&](Error Err) {
-    cantFail(std::move(Err));
-    OnReadyRun = true;
+    OnCompletionRun = true;
   };
 
-  AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), OnResolution, OnReady);
+  AsynchronousSymbolQuery Q(SymbolNameSet({Foo}), SymbolState::Ready,
+                            OnCompletion);
 
   ES.legacyFailQuery(Q,
                      make_error<StringError>("xyz", inconvertibleErrorCode()));
 
-  EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
-  EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
+  EXPECT_TRUE(OnCompletionRun) << "OnCompletionCallback was not run";
 }
 
 TEST_F(CoreAPIsStandardTest, EmptyLookup) {
-  bool OnResolvedRun = false;
-  bool OnReadyRun = false;
+  bool OnCompletionRun = false;
 
-  auto OnResolution = [&](Expected<SymbolMap> Result) {
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
     cantFail(std::move(Result));
-    OnResolvedRun = true;
+    OnCompletionRun = true;
   };
 
-  auto OnReady = [&](Error Err) {
-    cantFail(std::move(Err));
-    OnReadyRun = true;
-  };
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {}, SymbolState::Ready,
+            OnCompletion, NoDependenciesToRegister);
 
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {}, OnResolution, OnReady,
-            NoDependenciesToRegister);
-
-  EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
-  EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
+  EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run for empty query";
 }
 
 TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) {
@@ -128,8 +109,8 @@
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
       [this](MaterializationResponsibility R) {
         ADD_FAILURE() << "Unexpected materialization of \"Bar\"";
-        R.resolve({{Bar, BarSym}});
-        R.emit();
+        R.notifyResolved({{Bar, BarSym}});
+        R.notifyEmitted();
       },
       [&](const JITDylib &JD, const SymbolStringPtr &Name) {
         EXPECT_EQ(Name, Bar) << "Expected \"Bar\" to be discarded";
@@ -148,20 +129,14 @@
         ADD_FAILURE() << "\"Baz\" discarded unexpectedly";
       })));
 
-  bool OnResolvedRun = false;
-  bool OnReadyRun = false;
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo, Baz},
-            [&](Expected<SymbolMap> Result) {
-              EXPECT_TRUE(!!Result) << "OnResolved failed unexpectedly";
-              consumeError(Result.takeError());
-              OnResolvedRun = true;
-            },
-            [&](Error Err) {
-              EXPECT_FALSE(!!Err) << "OnReady failed unexpectedly";
-              consumeError(std::move(Err));
-              OnReadyRun = true;
-            },
-            NoDependenciesToRegister);
+  bool OnCompletionRun = false;
+  ES.lookup(
+      JITDylibSearchList({{&JD, false}}), {Foo, Baz}, SymbolState::Ready,
+      [&](Expected<SymbolMap> Result) {
+        cantFail(Result.takeError());
+        OnCompletionRun = true;
+      },
+      NoDependenciesToRegister);
 
   {
     // Attempt 1: Search for a missing symbol, Qux.
@@ -181,8 +156,8 @@
     consumeError(std::move(Err));
   }
 
-  BazR->resolve({{Baz, BazSym}});
-  BazR->emit();
+  BazR->notifyResolved({{Baz, BazSym}});
+  BazR->notifyEmitted();
   {
     // Attempt 3: Search now that all symbols are fully materialized
     // (Foo, Baz), or not yet materialized (Bar).
@@ -193,8 +168,7 @@
   EXPECT_TRUE(BarDiscarded) << "\"Bar\" should have been discarded";
   EXPECT_TRUE(BarMaterializerDestructed)
       << "\"Bar\"'s materializer should have been destructed";
-  EXPECT_TRUE(OnResolvedRun) << "OnResolved should have been run";
-  EXPECT_TRUE(OnReadyRun) << "OnReady should have been run";
+  EXPECT_TRUE(OnCompletionRun) << "OnCompletion should have been run";
 }
 
 TEST_F(CoreAPIsStandardTest, ChainedJITDylibLookup) {
@@ -202,24 +176,18 @@
 
   auto &JD2 = ES.createJITDylib("JD2");
 
-  bool OnResolvedRun = false;
-  bool OnReadyRun = false;
+  bool OnCompletionRun = false;
 
   auto Q = std::make_shared<AsynchronousSymbolQuery>(
-      SymbolNameSet({Foo}),
+      SymbolNameSet({Foo}), SymbolState::Ready,
       [&](Expected<SymbolMap> Result) {
         cantFail(std::move(Result));
-        OnResolvedRun = true;
-      },
-      [&](Error Err) {
-        cantFail(std::move(Err));
-        OnReadyRun = true;
+        OnCompletionRun = true;
       });
 
-  JD2.legacyLookup(Q, JD.legacyLookup(Q, {Foo}));
+  cantFail(JD2.legacyLookup(Q, cantFail(JD.legacyLookup(Q, {Foo}))));
 
-  EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run for empty query";
-  EXPECT_TRUE(OnReadyRun) << "OnReady was not run for empty query";
+  EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run for empty query";
 }
 
 TEST_F(CoreAPIsStandardTest, LookupWithHiddenSymbols) {
@@ -260,7 +228,7 @@
 
   SymbolNameSet Names({Foo, Bar, Baz});
 
-  auto SymbolFlags = JD.lookupFlags(Names);
+  auto SymbolFlags = cantFail(JD.lookupFlags(Names));
 
   EXPECT_EQ(SymbolFlags.size(), 2U)
       << "Returned symbol flags contains unexpected results";
@@ -273,6 +241,27 @@
       << "Incorrect flags returned for Bar";
 }
 
+TEST_F(CoreAPIsStandardTest, LookupWithGeneratorFailure) {
+
+  class BadGenerator {
+  public:
+    Expected<SymbolNameSet> operator()(JITDylib &, const SymbolNameSet &) {
+      return make_error<StringError>("BadGenerator", inconvertibleErrorCode());
+    }
+  };
+
+  JD.setGenerator(BadGenerator());
+
+  EXPECT_THAT_ERROR(JD.lookupFlags({Foo}).takeError(), Failed<StringError>())
+      << "Generator failure did not propagate through lookupFlags";
+
+  EXPECT_THAT_ERROR(
+      ES.lookup(JITDylibSearchList({{&JD, false}}), SymbolNameSet({Foo}))
+          .takeError(),
+      Failed<StringError>())
+      << "Generator failure did not propagate through lookup";
+}
+
 TEST_F(CoreAPIsStandardTest, TestBasicAliases) {
   cantFail(JD.define(absoluteSymbols({{Foo, FooSym}, {Bar, BarSym}})));
   cantFail(JD.define(symbolAliases({{Baz, {Foo, JITSymbolFlags::Exported}},
@@ -328,8 +317,8 @@
       SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
       [&](MaterializationResponsibility R) {
         BarMaterialized = true;
-        R.resolve({{Bar, BarSym}});
-        R.emit();
+        R.notifyResolved({{Bar, BarSym}});
+        R.notifyEmitted();
       });
 
   cantFail(JD.define(BarMU));
@@ -356,7 +345,7 @@
 
   JD.setGenerator(ReexportsGenerator(JD2, false, Filter));
 
-  auto Flags = JD.lookupFlags({Foo, Bar, Baz});
+  auto Flags = cantFail(JD.lookupFlags({Foo, Bar, Baz}));
   EXPECT_EQ(Flags.size(), 1U) << "Unexpected number of results";
   EXPECT_EQ(Flags[Foo], FooSym.getFlags()) << "Unexpected flags for Foo";
 
@@ -375,17 +364,16 @@
   cantFail(JD.define(FooMU));
 
   bool FooReady = false;
-  auto OnResolution = [](Expected<SymbolMap> R) { cantFail(std::move(R)); };
-  auto OnReady = [&](Error Err) {
-    cantFail(std::move(Err));
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
     FooReady = true;
   };
 
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
-            std::move(OnReady), NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+            OnCompletion, NoDependenciesToRegister);
 
-  FooR->resolve({{Foo, FooSym}});
-  FooR->emit();
+  FooR->notifyResolved({{Foo, FooSym}});
+  FooR->notifyEmitted();
 
   EXPECT_TRUE(FooReady)
     << "Self-dependency prevented symbol from being marked ready";
@@ -431,16 +419,18 @@
     FooResolved = true;
   };
 
-  auto OnFooReady = [&](Error Err) {
-    cantFail(std::move(Err));
+  auto OnFooReady = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
     FooReady = true;
   };
 
-  // Issue a lookup for Foo. Use NoDependenciesToRegister: We're going to add
+  // Issue lookups for Foo. Use NoDependenciesToRegister: We're going to add
   // the dependencies manually below.
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
-            std::move(OnFooResolution), std::move(OnFooReady),
-            NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+            std::move(OnFooResolution), NoDependenciesToRegister);
+
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+            std::move(OnFooReady), NoDependenciesToRegister);
 
   bool BarResolved = false;
   bool BarReady = false;
@@ -449,14 +439,16 @@
     BarResolved = true;
   };
 
-  auto OnBarReady = [&](Error Err) {
-    cantFail(std::move(Err));
+  auto OnBarReady = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
     BarReady = true;
   };
 
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar},
-            std::move(OnBarResolution), std::move(OnBarReady),
-            NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Resolved,
+            std::move(OnBarResolution), NoDependenciesToRegister);
+
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
+            std::move(OnBarReady), NoDependenciesToRegister);
 
   bool BazResolved = false;
   bool BazReady = false;
@@ -466,14 +458,16 @@
     BazResolved = true;
   };
 
-  auto OnBazReady = [&](Error Err) {
-    cantFail(std::move(Err));
+  auto OnBazReady = [&](Expected<SymbolMap> Result) {
+    cantFail(std::move(Result));
     BazReady = true;
   };
 
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz},
-            std::move(OnBazResolution), std::move(OnBazReady),
-            NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Resolved,
+            std::move(OnBazResolution), NoDependenciesToRegister);
+
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Baz}, SymbolState::Ready,
+            std::move(OnBazReady), NoDependenciesToRegister);
 
   // Add a circular dependency: Foo -> Bar, Bar -> Baz, Baz -> Foo.
   FooR->addDependenciesForAll({{&JD, SymbolNameSet({Bar})}});
@@ -492,9 +486,9 @@
   EXPECT_FALSE(BazResolved) << "\"Baz\" should not be resolved yet";
 
   // Resolve the symbols (but do not emit them).
-  FooR->resolve({{Foo, FooSym}});
-  BarR->resolve({{Bar, BarSym}});
-  BazR->resolve({{Baz, BazSym}});
+  FooR->notifyResolved({{Foo, FooSym}});
+  BarR->notifyResolved({{Bar, BarSym}});
+  BazR->notifyResolved({{Baz, BazSym}});
 
   // Verify that the symbols have been resolved, but are not ready yet.
   EXPECT_TRUE(FooResolved) << "\"Foo\" should be resolved now";
@@ -506,8 +500,8 @@
   EXPECT_FALSE(BazReady) << "\"Baz\" should not be ready yet";
 
   // Emit two of the symbols.
-  FooR->emit();
-  BarR->emit();
+  FooR->notifyEmitted();
+  BarR->notifyEmitted();
 
   // Verify that nothing is ready until the circular dependence is resolved.
   EXPECT_FALSE(FooReady) << "\"Foo\" still should not be ready";
@@ -515,7 +509,7 @@
   EXPECT_FALSE(BazReady) << "\"Baz\" still should not be ready";
 
   // Emit the last symbol.
-  BazR->emit();
+  BazR->notifyEmitted();
 
   // Verify that everything becomes ready once the circular dependence resolved.
   EXPECT_TRUE(FooReady) << "\"Foo\" should be ready now";
@@ -564,8 +558,8 @@
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}),
       [&](MaterializationResponsibility R) {
         assert(BarDiscarded && "Bar should have been discarded by this point");
-        R.resolve(SymbolMap({{Foo, FooSym}}));
-        R.emit();
+        R.notifyResolved(SymbolMap({{Foo, FooSym}}));
+        R.notifyEmitted();
         FooMaterialized = true;
       },
       [&](const JITDylib &JD, SymbolStringPtr Name) {
@@ -578,30 +572,23 @@
 
   SymbolNameSet Names({Foo});
 
-  bool OnResolutionRun = false;
-  bool OnReadyRun = false;
+  bool OnCompletionRun = false;
 
-  auto OnResolution = [&](Expected<SymbolMap> Result) {
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
     EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
     auto I = Result->find(Foo);
     EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
     EXPECT_EQ(I->second.getAddress(), FooSym.getAddress())
         << "Resolution returned incorrect result";
-    OnResolutionRun = true;
+    OnCompletionRun = true;
   };
 
-  auto OnReady = [&](Error Err) {
-    cantFail(std::move(Err));
-    OnReadyRun = true;
-  };
-
-  ES.lookup(JITDylibSearchList({{&JD, false}}), Names, std::move(OnResolution),
-            std::move(OnReady), NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), Names, SymbolState::Ready,
+            std::move(OnCompletion), NoDependenciesToRegister);
 
   EXPECT_TRUE(FooMaterialized) << "Foo was not materialized";
   EXPECT_TRUE(BarDiscarded) << "Bar was not discarded";
-  EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
-  EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
+  EXPECT_TRUE(OnCompletionRun) << "OnResolutionCallback was not run";
 }
 
 TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) {
@@ -612,7 +599,7 @@
   auto MU1 = llvm::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
       [&](MaterializationResponsibility R) {
-        R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})), R.emit();
+        R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}})), R.notifyEmitted();
         BarMaterialized = true;
       });
 
@@ -631,24 +618,17 @@
   cantFail(JD.define(MU1));
   cantFail(JD.define(MU2));
 
-  bool OnResolvedRun = false;
-  bool OnReadyRun = false;
+  bool OnCompletionRun = false;
 
-  auto OnResolution = [&](Expected<SymbolMap> Result) {
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
     cantFail(std::move(Result));
-    OnResolvedRun = true;
+    OnCompletionRun = true;
   };
 
-  auto OnReady = [&](Error Err) {
-    cantFail(std::move(Err));
-    OnReadyRun = true;
-  };
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, SymbolState::Ready,
+            std::move(OnCompletion), NoDependenciesToRegister);
 
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Bar}, std::move(OnResolution),
-            std::move(OnReady), NoDependenciesToRegister);
-
-  EXPECT_TRUE(OnResolvedRun) << "OnResolved not run";
-  EXPECT_TRUE(OnReadyRun) << "OnReady not run";
+  EXPECT_TRUE(OnCompletionRun) << "OnCompletion not run";
   EXPECT_TRUE(BarMaterialized) << "Bar was not materialized at all";
   EXPECT_TRUE(DuplicateBarDiscarded)
       << "Duplicate bar definition not discarded";
@@ -668,8 +648,8 @@
       [&](MaterializationResponsibility R) {
         cantFail(
             R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}})));
-        R.resolve(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
-        R.emit();
+        R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
+        R.notifyEmitted();
       });
 
   cantFail(JD.define(MU));
@@ -704,7 +684,11 @@
   auto MU = llvm::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak},
                       {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}),
-      [&](MaterializationResponsibility R) { R.failMaterialization(); });
+      [&](MaterializationResponsibility R) {
+        dbgs() << "Before failMat:\n";
+        ES.dump(dbgs());
+        R.failMaterialization();
+      });
 
   cantFail(JD.define(MU));
 
@@ -731,12 +715,47 @@
   }
 }
 
+TEST_F(CoreAPIsStandardTest, FailEmissionEarly) {
+
+  cantFail(JD.define(absoluteSymbols({{Baz, BazSym}})));
+
+  auto MU = llvm::make_unique<SimpleMaterializationUnit>(
+      SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}),
+      [&](MaterializationResponsibility R) {
+        R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}));
+
+        ES.lookup(
+            JITDylibSearchList({{&JD, false}}), SymbolNameSet({Baz}),
+            SymbolState::Resolved,
+            [&R](Expected<SymbolMap> Result) {
+              // Called when "baz" is resolved. We don't actually depend
+              // on or care about baz, but use it to trigger failure of
+              // this materialization before Baz has been finalized in
+              // order to test that error propagation is correct in this
+              // scenario.
+              cantFail(std::move(Result));
+              R.failMaterialization();
+            },
+            [&](const SymbolDependenceMap &Deps) {
+              R.addDependenciesForAll(Deps);
+            });
+      });
+
+  cantFail(JD.define(MU));
+
+  SymbolNameSet Names({Foo, Bar});
+  auto Result = ES.lookup(JITDylibSearchList({{&JD, false}}), Names);
+
+  EXPECT_THAT_EXPECTED(std::move(Result), Failed())
+      << "Unexpected success while trying to test error propagation";
+}
+
 TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) {
   auto MU = llvm::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
       [&](MaterializationResponsibility R) {
-        R.resolve({{Foo, FooSym}});
-        R.emit();
+        R.notifyResolved({{Foo, FooSym}});
+        R.notifyEmitted();
       });
 
   cantFail(JD.define(MU));
@@ -794,15 +813,15 @@
         auto NewMU = llvm::make_unique<SimpleMaterializationUnit>(
             SymbolFlagsMap({{Bar, BarSym.getFlags()}}),
             [&](MaterializationResponsibility R2) {
-              R2.resolve(SymbolMap({{Bar, BarSym}}));
-              R2.emit();
+              R2.notifyResolved(SymbolMap({{Bar, BarSym}}));
+              R2.notifyEmitted();
               BarMaterialized = true;
             });
 
         R.replace(std::move(NewMU));
 
-        R.resolve(SymbolMap({{Foo, FooSym}}));
-        R.emit();
+        R.notifyResolved(SymbolMap({{Foo, FooSym}}));
+        R.notifyEmitted();
 
         FooMaterialized = true;
       });
@@ -833,10 +852,10 @@
       [&](MaterializationResponsibility R) {
         auto R2 = R.delegate({Bar});
 
-        R.resolve({{Foo, FooSym}});
-        R.emit();
-        R2.resolve({{Bar, BarSym}});
-        R2.emit();
+        R.notifyResolved({{Foo, FooSym}});
+        R.notifyEmitted();
+        R2.notifyResolved({{Bar, BarSym}});
+        R2.notifyEmitted();
       });
 
   cantFail(JD.define(MU));
@@ -867,14 +886,12 @@
       });
 
   cantFail(JD.define(MU));
-  auto OnResolution = [](Expected<SymbolMap> Result) {
+  auto OnCompletion = [](Expected<SymbolMap> Result) {
     cantFail(std::move(Result));
   };
 
-  auto OnReady = [](Error Err) { cantFail(std::move(Err)); };
-
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, std::move(OnResolution),
-            std::move(OnReady), NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Ready,
+            std::move(OnCompletion), NoDependenciesToRegister);
 
   auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
       SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
@@ -888,8 +905,8 @@
       << "Expected a duplicate definition error";
   consumeError(std::move(Err));
 
-  FooResponsibility->resolve(SymbolMap({{Foo, FooSym}}));
-  FooResponsibility->emit();
+  FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}}));
+  FooResponsibility->notifyEmitted();
 }
 
 } // namespace
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
index d093b2a..d3853df 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp
@@ -1,9 +1,8 @@
 //===--- GlobalMappingLayerTest.cpp - Unit test the global mapping layer --===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
index 1dfa0a1..e9d39ef 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
@@ -1,9 +1,8 @@
 //===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp
index f978a90..1f3626e 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/JITTargetMachineBuilderTest.cpp
@@ -1,9 +1,8 @@
 //===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
index ebe99d4..87d582b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp
@@ -41,12 +41,12 @@
       SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}),
       [&](MaterializationResponsibility R) {
         DummyTargetMaterialized = true;
-        R.resolve(
+        R.notifyResolved(
             {{DummyTarget,
               JITEvaluatedSymbol(static_cast<JITTargetAddress>(
                                      reinterpret_cast<uintptr_t>(&dummyTarget)),
                                  JITSymbolFlags::Exported)}});
-        R.emit();
+        R.notifyEmitted();
       })));
 
   unsigned NotifyResolvedCount = 0;
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
index 3801fa9..cc67aa0 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
@@ -1,9 +1,8 @@
 //===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -23,7 +22,8 @@
 
 TEST(LazyEmittingLayerTest, Empty) {
   MockBaseLayer M;
-  llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
+  llvm::orc::LazyEmittingLayer<MockBaseLayer> L(
+      llvm::AcknowledgeORCv1Deprecation, M);
   cantFail(
       L.addModule(llvm::orc::VModuleKey(), std::unique_ptr<llvm::Module>()));
 }
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
index 36cb710..f79d721 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp
@@ -1,9 +1,8 @@
 //===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -25,7 +24,7 @@
 
   auto Resolver = createSymbolResolver(
       [&](const SymbolNameSet &Symbols) {
-        auto FlagsMap = JD.lookupFlags(Symbols);
+        auto FlagsMap = cantFail(JD.lookupFlags(Symbols));
         SymbolNameSet Result;
         for (auto &KV : FlagsMap)
           if (!KV.second.isStrong())
@@ -33,7 +32,7 @@
         return Result;
       },
       [&](std::shared_ptr<AsynchronousSymbolQuery> Q, SymbolNameSet Symbols) {
-        return JD.legacyLookup(std::move(Q), Symbols);
+        return cantFail(JD.legacyLookup(std::move(Q), Symbols));
       });
 
   auto RS = Resolver->getResponsibilitySet(SymbolNameSet({Bar, Baz}));
@@ -43,10 +42,10 @@
   EXPECT_EQ(RS.count(Bar), 1U)
       << "getResponsibilitySet result incorrect. Should be {'bar'}";
 
-  bool OnResolvedRun = false;
+  bool OnCompletionRun = false;
 
-  auto OnResolved = [&](Expected<SymbolMap> Result) {
-    OnResolvedRun = true;
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
+    OnCompletionRun = true;
     EXPECT_TRUE(!!Result) << "Unexpected error";
     EXPECT_EQ(Result->size(), 2U) << "Unexpected number of resolved symbols";
     EXPECT_EQ(Result->count(Foo), 1U) << "Missing lookup result for foo";
@@ -56,18 +55,15 @@
     EXPECT_EQ((*Result)[Bar].getAddress(), BarSym.getAddress())
         << "Incorrect address for bar";
   };
-  auto OnReady = [&](Error Err) {
-    EXPECT_FALSE(!!Err) << "Finalization should never fail in this test";
-  };
 
-  auto Q = std::make_shared<AsynchronousSymbolQuery>(SymbolNameSet({Foo, Bar}),
-                                                     OnResolved, OnReady);
+  auto Q = std::make_shared<AsynchronousSymbolQuery>(
+      SymbolNameSet({Foo, Bar}), SymbolState::Resolved, OnCompletion);
   auto Unresolved =
       Resolver->lookup(std::move(Q), SymbolNameSet({Foo, Bar, Baz}));
 
   EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
   EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to not be resolved";
-  EXPECT_TRUE(OnResolvedRun) << "OnResolved was never run";
+  EXPECT_TRUE(OnCompletionRun) << "OnCompletion was never run";
 }
 
 TEST_F(LegacyAPIsStandardTest, LegacyLookupHelpersFn) {
@@ -99,10 +95,9 @@
   EXPECT_FALSE(BarMaterialized)
       << "lookupFlags should not have materialized bar";
 
-  bool OnResolvedRun = false;
-  bool OnReadyRun = false;
-  auto OnResolved = [&](Expected<SymbolMap> Result) {
-    OnResolvedRun = true;
+  bool OnCompletionRun = false;
+  auto OnCompletion = [&](Expected<SymbolMap> Result) {
+    OnCompletionRun = true;
     EXPECT_TRUE(!!Result) << "lookuWithLegacy failed to resolve";
 
     EXPECT_EQ(Result->size(), 2U) << "Wrong number of symbols resolved";
@@ -115,17 +110,12 @@
     EXPECT_EQ((*Result)[Bar].getFlags(), BarSym.getFlags())
         << "Wrong flags for bar";
   };
-  auto OnReady = [&](Error Err) {
-    EXPECT_FALSE(!!Err) << "Finalization unexpectedly failed";
-    OnReadyRun = true;
-  };
 
-  AsynchronousSymbolQuery Q({Foo, Bar}, OnResolved, OnReady);
+  AsynchronousSymbolQuery Q({Foo, Bar}, SymbolState::Resolved, OnCompletion);
   auto Unresolved =
       lookupWithLegacyFn(ES, Q, SymbolNameSet({Foo, Bar, Baz}), LegacyLookup);
 
-  EXPECT_TRUE(OnResolvedRun) << "OnResolved was not run";
-  EXPECT_TRUE(OnReadyRun) << "OnReady was not run";
+  EXPECT_TRUE(OnCompletionRun) << "OnCompletion was not run";
   EXPECT_EQ(Unresolved.size(), 1U) << "Expected one unresolved symbol";
   EXPECT_EQ(Unresolved.count(Baz), 1U) << "Expected baz to be unresolved";
 }
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
index 38f7a65..06b96f9 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp
@@ -1,9 +1,8 @@
 //===----- CompileOnDemandLayerTest.cpp - Unit tests for the COD layer ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -77,7 +76,7 @@
   };
 
   llvm::orc::LegacyCompileOnDemandLayer<decltype(TestBaseLayer)> COD(
-      ES, TestBaseLayer, GetResolver, SetResolver,
+      AcknowledgeORCv1Deprecation, ES, TestBaseLayer, GetResolver, SetResolver,
       [](Function &F) { return std::set<Function *>{&F}; }, CallbackMgr,
       [] { return llvm::make_unique<DummyStubsManager>(); }, true);
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
index b3696c6..001019d 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp
@@ -1,9 +1,8 @@
 //===- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer unit tests -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -69,10 +68,11 @@
 
   ExecutionSession ES;
 
-  LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey) {
-    return LegacyRTDyldObjectLinkingLayer::Resources{
-        MM, std::make_shared<NullResolver>()};
-  });
+  LegacyRTDyldObjectLinkingLayer ObjLayer(
+      AcknowledgeORCv1Deprecation, ES, [&MM](VModuleKey) {
+        return LegacyRTDyldObjectLinkingLayer::Resources{
+            MM, std::make_shared<NullResolver>()};
+      });
 
   LLVMContext Context;
   auto M = llvm::make_unique<Module>("", Context);
@@ -131,13 +131,14 @@
 
   std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>> Resolvers;
 
-  LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&](VModuleKey K) {
-    auto I = Resolvers.find(K);
-    assert(I != Resolvers.end() && "Missing resolver");
-    auto R = std::move(I->second);
-    Resolvers.erase(I);
-    return LegacyRTDyldObjectLinkingLayer::Resources{MM, std::move(R)};
-  });
+  LegacyRTDyldObjectLinkingLayer ObjLayer(
+      AcknowledgeORCv1Deprecation, ES, [&](VModuleKey K) {
+        auto I = Resolvers.find(K);
+        assert(I != Resolvers.end() && "Missing resolver");
+        auto R = std::move(I->second);
+        Resolvers.erase(I);
+        return LegacyRTDyldObjectLinkingLayer::Resources{MM, std::move(R)};
+      });
   SimpleCompiler Compile(*TM);
 
   // Create a pair of modules that will trigger recursive finalization:
@@ -218,10 +219,11 @@
 
   auto MM = std::make_shared<SectionMemoryManagerWrapper>();
 
-  LegacyRTDyldObjectLinkingLayer ObjLayer(ES, [&MM](VModuleKey K) {
-    return LegacyRTDyldObjectLinkingLayer::Resources{
-        MM, std::make_shared<NullResolver>()};
-  });
+  LegacyRTDyldObjectLinkingLayer ObjLayer(
+      AcknowledgeORCv1Deprecation, ES, [&MM](VModuleKey K) {
+        return LegacyRTDyldObjectLinkingLayer::Resources{
+            MM, std::make_shared<NullResolver>()};
+      });
   SimpleCompiler Compile(*TM);
 
   // Create a pair of unrelated modules:
@@ -279,7 +281,7 @@
 TEST_F(LegacyRTDyldObjectLinkingLayerExecutionTest, TestNotifyLoadedSignature) {
   ExecutionSession ES;
   LegacyRTDyldObjectLinkingLayer ObjLayer(
-      ES,
+      AcknowledgeORCv1Deprecation, ES,
       [](VModuleKey) {
         return LegacyRTDyldObjectLinkingLayer::Resources{
             nullptr, std::make_shared<NullResolver>()};
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
index 1c53024..2ff7e91 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp
@@ -1,9 +1,8 @@
 //===- ObjectTransformLayerTest.cpp - Unit tests for ObjectTransformLayer -===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -183,17 +182,19 @@
 
   // Create one object transform layer using a transform (as a functor)
   // that allocates new objects, and deals in unique pointers.
-  LegacyObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
+  LegacyObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(
+      llvm::AcknowledgeORCv1Deprecation, M);
 
   // Create a second object transform layer using a transform (as a lambda)
   // that mutates objects in place, and deals in naked pointers
   LegacyObjectTransformLayer<MockBaseLayer,
-                         std::function<std::shared_ptr<MockObjectFile>(
-                           std::shared_ptr<MockObjectFile>)>>
-    T2(M, [](std::shared_ptr<MockObjectFile> Obj) {
-    ++(*Obj);
-    return Obj;
-  });
+                             std::function<std::shared_ptr<MockObjectFile>(
+                                 std::shared_ptr<MockObjectFile>)>>
+      T2(llvm::AcknowledgeORCv1Deprecation, M,
+         [](std::shared_ptr<MockObjectFile> Obj) {
+           ++(*Obj);
+           return Obj;
+         });
 
   // Test addObject with T1 (allocating)
   auto K1 = ES.allocateVModule();
@@ -282,22 +283,25 @@
   };
 
   // Construct the jit layers.
-  LegacyRTDyldObjectLinkingLayer BaseLayer(ES, [](VModuleKey) {
-    return LegacyRTDyldObjectLinkingLayer::Resources{
-        std::make_shared<llvm::SectionMemoryManager>(),
-        std::make_shared<NullResolver>()};
-  });
+  LegacyRTDyldObjectLinkingLayer BaseLayer(
+      llvm::AcknowledgeORCv1Deprecation, ES, [](VModuleKey) {
+        return LegacyRTDyldObjectLinkingLayer::Resources{
+            std::make_shared<llvm::SectionMemoryManager>(),
+            std::make_shared<NullResolver>()};
+      });
 
   auto IdentityTransform = [](std::unique_ptr<llvm::MemoryBuffer> Obj) {
     return Obj;
   };
   LegacyObjectTransformLayer<decltype(BaseLayer), decltype(IdentityTransform)>
-      TransformLayer(BaseLayer, IdentityTransform);
+      TransformLayer(llvm::AcknowledgeORCv1Deprecation, BaseLayer,
+                     IdentityTransform);
   auto NullCompiler = [](llvm::Module &) {
     return std::unique_ptr<llvm::MemoryBuffer>(nullptr);
   };
   LegacyIRCompileLayer<decltype(TransformLayer), decltype(NullCompiler)>
-    CompileLayer(TransformLayer, NullCompiler);
+      CompileLayer(llvm::AcknowledgeORCv1Deprecation, TransformLayer,
+                   NullCompiler);
 
   // Make sure that the calls from LegacyIRCompileLayer to LegacyObjectTransformLayer
   // compile.
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
index 54d8156..39fdc2e 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
@@ -1,9 +1,8 @@
 //===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
index a12b187..2a3223a 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
@@ -1,9 +1,8 @@
 //===--------- OrcTestCommon.cpp - Utilities for Orc Unit Tests -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
index e25c513..d82012b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -1,9 +1,8 @@
 //===------ OrcTestCommon.h - Utilities for Orc Unit Tests ------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp
index e309a7e..7556f8a 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.cpp
@@ -1,9 +1,8 @@
 //===-------- QueueChannel.cpp - Unit tests the remote executors ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h
index d8c1681..56a3926 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h
@@ -1,9 +1,8 @@
 //===----------------------- Queue.h - RPC Queue ------------------*-c++-*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
index c884aaa..1f7c88d 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
@@ -1,9 +1,8 @@
 //===----------- RPCUtilsTest.cpp - Unit tests the Orc RPC utils ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
index 2db237f..440b840 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
@@ -1,9 +1,8 @@
 //===--- RTDyldObjectLinkingLayerTest.cpp - RTDyld linking layer tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -62,12 +61,11 @@
     cantFail(std::move(R));
   };
 
-  auto OnReadyDoNothing = [](Error Err) { cantFail(std::move(Err)); };
-
   ObjLayer.setProcessAllSections(ProcessAllSections);
   cantFail(ObjLayer.add(JD, std::move(Obj), ES.allocateVModule()));
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, OnResolveDoNothing,
-            OnReadyDoNothing, NoDependenciesToRegister);
+  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+            OnResolveDoNothing, NoDependenciesToRegister);
+
   return DebugSectionSeen;
 }
 
@@ -161,10 +159,10 @@
   ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
 
   cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
-            [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
-            [](Error Err) { cantFail(std::move(Err)); },
-            NoDependenciesToRegister);
+  ES.lookup(
+      JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+      [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
+      NoDependenciesToRegister);
 }
 
 TEST(RTDyldObjectLinkingLayerTest, TestAutoClaimResponsibilityForSymbols) {
@@ -226,10 +224,10 @@
   ObjLayer.setAutoClaimResponsibilityForObjectSymbols(true);
 
   cantFail(CompileLayer.add(JD, std::move(M), ES.allocateVModule()));
-  ES.lookup(JITDylibSearchList({{&JD, false}}), {Foo},
-            [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
-            [](Error Err) { cantFail(std::move(Err)); },
-            NoDependenciesToRegister);
+  ES.lookup(
+      JITDylibSearchList({{&JD, false}}), {Foo}, SymbolState::Resolved,
+      [](Expected<SymbolMap> R) { cantFail(std::move(R)); },
+      NoDependenciesToRegister);
 }
 
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp
index 4ffd741..4377d52 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp
@@ -1,9 +1,8 @@
 //===---------------------- RemoteObjectLayerTest.cpp ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -128,7 +127,8 @@
   std::copy(ObjBytes.begin(), ObjBytes.end(), ObjContents.begin());
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
   MockObjectLayer BaseLayer(
@@ -145,9 +145,8 @@
 
       return 1;
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -182,7 +181,8 @@
     };
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
   MockObjectLayer BaseLayer(
@@ -192,9 +192,8 @@
       return make_error<StringError>("AddObjectFailure - Test Message",
                                      inconvertibleErrorCode());
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -234,7 +233,8 @@
   };
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
 
@@ -244,9 +244,8 @@
       SymTab[1] = MockObjectLayer::LookupFn();
       return 1;
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -284,7 +283,8 @@
     };
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
 
@@ -295,9 +295,8 @@
        MockObjectLayer::SymbolLookupTable &SymTab) {
       return 42;
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -340,7 +339,8 @@
     };
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
 
@@ -359,9 +359,8 @@
         };
       return 42;
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -422,7 +421,8 @@
     };
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
 
@@ -448,9 +448,8 @@
 
       return 42;
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -497,7 +496,8 @@
   };
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
 
@@ -507,9 +507,8 @@
       SymTab[1] = MockObjectLayer::LookupFn();
       return 1;
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
@@ -548,7 +547,8 @@
     };
 
   RPCEndpoint ClientEP(*Channels.first, true);
-  RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);
+  RemoteObjectClientLayer<RPCEndpoint> Client(AcknowledgeORCv1Deprecation,
+                                              ClientEP, ReportError);
 
   RPCEndpoint ServerEP(*Channels.second, true);
 
@@ -557,9 +557,8 @@
        MockObjectLayer::SymbolLookupTable &SymTab) {
       return 1;
     });
-  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,
-                                                               ServerEP,
-                                                               ReportError);
+  RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(
+      AcknowledgeORCv1Deprecation, BaseLayer, ServerEP, ReportError);
 
   bool Finished = false;
   ServerEP.addHandler<remote::utils::TerminateSession>(
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp
index 861a966..a68da0b 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/SymbolStringPoolTest.cpp
@@ -1,9 +1,8 @@
 //===----- SymbolStringPoolTest.cpp - Unit tests for SymbolStringPool -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp
index eb2cd41..6cd6c20 100644
--- a/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp
+++ b/src/llvm-project/llvm/unittests/ExecutionEngine/Orc/ThreadSafeModuleTest.cpp
@@ -1,9 +1,8 @@
 //===--- ThreadSafeModuleTest.cpp - Test basic use of ThreadSafeModule ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp
index 0fc6b2c..a077c5c 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/OperationsTest.cpp
@@ -1,9 +1,8 @@
 //===- OperationsTest.cpp - Tests for fuzzer operations -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp
index d6ad07d..1528be6 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/RandomIRBuilderTest.cpp
@@ -1,9 +1,8 @@
 //===- RandomIRBuilderTest.cpp - Tests for injector strategy --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp
index d246ba1..ac9270a 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/ReservoirSamplerTest.cpp
@@ -1,9 +1,8 @@
 //===- ReservoirSampler.cpp - Tests for the ReservoirSampler --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp b/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp
index 320a4e9..9ef88e2 100644
--- a/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp
+++ b/src/llvm-project/llvm/unittests/FuzzMutate/StrategiesTest.cpp
@@ -1,9 +1,8 @@
 //===- InjectorIRStrategyTest.cpp - Tests for injector strategy -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp b/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp
index 9ad5523..0e13cca 100644
--- a/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/AsmWriterTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/AsmWriter.cpp - AsmWriter tests -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/BinaryFormat/Dwarf.h"
diff --git a/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp b/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp
index dd88cc3..06da35a 100644
--- a/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/AttributesTest.cpp
@@ -1,14 +1,14 @@
 //===- llvm/unittest/IR/AttributesTest.cpp - Attributes unit tests --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/DerivedTypes.h"
 #include "gtest/gtest.h"
 using namespace llvm;
 
@@ -41,6 +41,10 @@
   EXPECT_TRUE(Align4 < Deref5);
   EXPECT_TRUE(Align5 < Deref4);
 
+  Attribute ByVal = Attribute::get(C, Attribute::ByVal, Type::getInt32Ty(C));
+  EXPECT_FALSE(ByVal < Attribute::get(C, Attribute::ZExt));
+  EXPECT_TRUE(ByVal < Align4);
+
   AttributeList ASs[] = {AttributeList::get(C, 2, Attribute::ZExt),
                          AttributeList::get(C, 1, Attribute::SExt)};
 
@@ -167,4 +171,19 @@
   EXPECT_EQ(2U, AL.getNumAttrSets());
 }
 
+TEST(Attributes, StringRepresentation) {
+  LLVMContext C;
+  StructType *Ty = StructType::create(Type::getInt32Ty(C), "mystruct");
+
+  // Insufficiently careful printing can result in byval(%mystruct = { i32 })
+  Attribute A = Attribute::getWithByValType(C, Ty);
+  EXPECT_EQ(A.getAsString(), "byval(%mystruct)");
+
+  A = Attribute::getWithByValType(C, nullptr);
+  EXPECT_EQ(A.getAsString(), "byval");
+
+  A = Attribute::getWithByValType(C, Type::getInt32Ty(C));
+  EXPECT_EQ(A.getAsString(), "byval(i32)");
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp b/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp
index 07ed997..95bc242 100644
--- a/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/BasicBlockTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/BasicBlockTest.cpp - BasicBlock unit tests --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -101,10 +100,9 @@
   Argument *V = new Argument(Type::getInt32Ty(Ctx));
   Function *F = Function::Create(FT, Function::ExternalLinkage, "", M);
 
-  Value *DbgAddr = Intrinsic::getDeclaration(M, Intrinsic::dbg_addr);
-  Value *DbgDeclare =
-      Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
-  Value *DbgValue = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
+  Function *DbgAddr = Intrinsic::getDeclaration(M, Intrinsic::dbg_addr);
+  Function *DbgDeclare = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
+  Function *DbgValue = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
   Value *DIV = MetadataAsValue::get(Ctx, (Metadata *)nullptr);
   SmallVector<Value *, 3> Args = {DIV, DIV, DIV};
 
diff --git a/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp b/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp
index 886ab8a..1ce5987 100644
--- a/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp
+++ b/src/llvm-project/llvm/unittests/IR/CFGBuilder.cpp
@@ -1,14 +1,14 @@
 //===- llvm/Testing/Support/CFGBuilder.cpp --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "CFGBuilder.h"
 
+#include "llvm/IR/CFG.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/Debug.h"
@@ -23,7 +23,7 @@
     : Context(llvm::make_unique<LLVMContext>()),
       M(llvm::make_unique<Module>(ModuleName, *Context)) {
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Context), {}, false);
-  F = cast<Function>(M->getOrInsertFunction(FunctionName, FTy));
+  F = Function::Create(FTy, Function::ExternalLinkage, FunctionName, M.get());
 }
 CFGHolder::~CFGHolder() = default;
 
@@ -266,3 +266,11 @@
   EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("c")->getTerminator()));
   EXPECT_TRUE(isa<SwitchInst>(B.getOrAddBlock("d")->getTerminator()));
 }
+
+static_assert(is_trivially_copyable<succ_iterator>::value,
+              "trivially copyable");
+static_assert(is_trivially_copyable<succ_const_iterator>::value,
+              "trivially copyable");
+static_assert(is_trivially_copyable<succ_range>::value, "trivially copyable");
+static_assert(is_trivially_copyable<succ_const_range>::value,
+              "trivially copyable");
diff --git a/src/llvm-project/llvm/unittests/IR/CFGBuilder.h b/src/llvm-project/llvm/unittests/IR/CFGBuilder.h
index d9d9c37..97be4a1 100644
--- a/src/llvm-project/llvm/unittests/IR/CFGBuilder.h
+++ b/src/llvm-project/llvm/unittests/IR/CFGBuilder.h
@@ -1,9 +1,8 @@
 //===- CFGBuilder.h - CFG building and updating utility ----------*- C++ -*-==//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 /// \file
diff --git a/src/llvm-project/llvm/unittests/IR/CMakeLists.txt b/src/llvm-project/llvm/unittests/IR/CMakeLists.txt
index f33835f..d27c6d9 100644
--- a/src/llvm-project/llvm/unittests/IR/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/IR/CMakeLists.txt
@@ -13,11 +13,11 @@
   CFGBuilder.cpp
   ConstantRangeTest.cpp
   ConstantsTest.cpp
+  DataLayoutTest.cpp
   DebugInfoTest.cpp
   DebugTypeODRUniquingTest.cpp
   DominatorTreeTest.cpp
   DominatorTreeBatchUpdatesTest.cpp
-  DomTreeUpdaterTest.cpp
   FunctionTest.cpp
   PassBuilderCallbacksTest.cpp
   IRBuilderTest.cpp
@@ -30,12 +30,14 @@
   ModuleTest.cpp
   PassManagerTest.cpp
   PatternMatch.cpp
+  TimePassesTest.cpp
   TypesTest.cpp
   UseTest.cpp
   UserTest.cpp
   ValueHandleTest.cpp
   ValueMapTest.cpp
   ValueTest.cpp
+  VectorTypesTest.cpp
   VerifierTest.cpp
   WaymarkTest.cpp
   )
diff --git a/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp b/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp
index c0a30f1..c0166b2 100644
--- a/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ConstantRangeTest.cpp
@@ -1,15 +1,16 @@
 //===- ConstantRangeTest.cpp - ConstantRange tests ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/BitVector.h"
 #include "llvm/IR/ConstantRange.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/Support/KnownBits.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -25,7 +26,114 @@
   static ConstantRange Wrap;
 };
 
-ConstantRange ConstantRangeTest::Full(16);
+template<typename Fn>
+static void EnumerateConstantRanges(unsigned Bits, Fn TestFn) {
+  unsigned Max = 1 << Bits;
+  for (unsigned Lo = 0; Lo < Max; Lo++) {
+    for (unsigned Hi = 0; Hi < Max; Hi++) {
+      // Enforce ConstantRange invariant.
+      if (Lo == Hi && Lo != 0 && Lo != Max - 1)
+        continue;
+
+      ConstantRange CR(APInt(Bits, Lo), APInt(Bits, Hi));
+      TestFn(CR);
+    }
+  }
+}
+
+template<typename Fn>
+static void EnumerateTwoConstantRanges(unsigned Bits, Fn TestFn) {
+  EnumerateConstantRanges(Bits, [&](const ConstantRange &CR1) {
+    EnumerateConstantRanges(Bits, [&](const ConstantRange &CR2) {
+      TestFn(CR1, CR2);
+    });
+  });
+}
+
+template<typename Fn>
+static void ForeachNumInConstantRange(const ConstantRange &CR, Fn TestFn) {
+  if (!CR.isEmptySet()) {
+    APInt N = CR.getLower();
+    do TestFn(N);
+    while (++N != CR.getUpper());
+  }
+}
+
+template<typename Fn1, typename Fn2>
+static void TestUnsignedBinOpExhaustive(
+    Fn1 RangeFn, Fn2 IntFn,
+    bool SkipZeroRHS = false, bool CorrectnessOnly = false) {
+  unsigned Bits = 4;
+  EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
+                                       const ConstantRange &CR2) {
+    APInt Min = APInt::getMaxValue(Bits);
+    APInt Max = APInt::getMinValue(Bits);
+    ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+      ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+        if (SkipZeroRHS && N2 == 0)
+          return;
+
+        APInt N = IntFn(N1, N2);
+        if (N.ult(Min))
+          Min = N;
+        if (N.ugt(Max))
+          Max = N;
+      });
+    });
+
+    ConstantRange CR = RangeFn(CR1, CR2);
+    if (Min.ugt(Max)) {
+      EXPECT_TRUE(CR.isEmptySet());
+      return;
+    }
+
+    ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1);
+    if (CorrectnessOnly) {
+      EXPECT_TRUE(CR.contains(Exact));
+    } else {
+      EXPECT_EQ(Exact, CR);
+    }
+  });
+}
+
+template<typename Fn1, typename Fn2>
+static void TestSignedBinOpExhaustive(
+    Fn1 RangeFn, Fn2 IntFn,
+    bool SkipZeroRHS = false, bool CorrectnessOnly = false) {
+  unsigned Bits = 4;
+  EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
+                                       const ConstantRange &CR2) {
+    APInt Min = APInt::getSignedMaxValue(Bits);
+    APInt Max = APInt::getSignedMinValue(Bits);
+    ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+      ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+        if (SkipZeroRHS && N2 == 0)
+          return;
+
+        APInt N = IntFn(N1, N2);
+        if (N.slt(Min))
+          Min = N;
+        if (N.sgt(Max))
+          Max = N;
+      });
+    });
+
+    ConstantRange CR = RangeFn(CR1, CR2);
+    if (Min.sgt(Max)) {
+      EXPECT_TRUE(CR.isEmptySet());
+      return;
+    }
+
+    ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1);
+    if (CorrectnessOnly) {
+      EXPECT_TRUE(CR.contains(Exact));
+    } else {
+      EXPECT_EQ(Exact, CR);
+    }
+  });
+}
+
+ConstantRange ConstantRangeTest::Full(16, true);
 ConstantRange ConstantRangeTest::Empty(16, false);
 ConstantRange ConstantRangeTest::One(APInt(16, 0xa));
 ConstantRange ConstantRangeTest::Some(APInt(16, 0xa), APInt(16, 0xaaa));
@@ -122,18 +230,6 @@
   EXPECT_FALSE(Wrap.isSingleElement());
 }
 
-TEST_F(ConstantRangeTest, GetSetSize) {
-  EXPECT_EQ(Full.getSetSize(), APInt(17, 65536));
-  EXPECT_EQ(Empty.getSetSize(), APInt(17, 0));
-  EXPECT_EQ(One.getSetSize(), APInt(17, 1));
-  EXPECT_EQ(Some.getSetSize(), APInt(17, 0xaa0));
-
-  ConstantRange Wrap(APInt(4, 7), APInt(4, 3));
-  ConstantRange Wrap2(APInt(4, 8), APInt(4, 7));
-  EXPECT_EQ(Wrap.getSetSize(), APInt(5, 12));
-  EXPECT_EQ(Wrap2.getSetSize(), APInt(5, 15));
-}
-
 TEST_F(ConstantRangeTest, GetMinsAndMaxes) {
   EXPECT_EQ(Full.getUnsignedMax(), APInt(16, UINT16_MAX));
   EXPECT_EQ(One.getUnsignedMax(), APInt(16, 0xa));
@@ -161,7 +257,7 @@
 }
 
 TEST_F(ConstantRangeTest, SignWrapped) {
-  EXPECT_TRUE(Full.isSignWrappedSet());
+  EXPECT_FALSE(Full.isSignWrappedSet());
   EXPECT_FALSE(Empty.isSignWrappedSet());
   EXPECT_FALSE(One.isSignWrappedSet());
   EXPECT_FALSE(Some.isSignWrappedSet());
@@ -176,6 +272,29 @@
   EXPECT_FALSE(ConstantRange(APInt(8, 250), APInt(8, 251)).isSignWrappedSet());
 }
 
+TEST_F(ConstantRangeTest, UpperWrapped) {
+  // The behavior here is the same as for isWrappedSet() / isSignWrappedSet().
+  EXPECT_FALSE(Full.isUpperWrapped());
+  EXPECT_FALSE(Empty.isUpperWrapped());
+  EXPECT_FALSE(One.isUpperWrapped());
+  EXPECT_FALSE(Some.isUpperWrapped());
+  EXPECT_TRUE(Wrap.isUpperWrapped());
+  EXPECT_FALSE(Full.isUpperSignWrapped());
+  EXPECT_FALSE(Empty.isUpperSignWrapped());
+  EXPECT_FALSE(One.isUpperSignWrapped());
+  EXPECT_FALSE(Some.isUpperSignWrapped());
+  EXPECT_TRUE(Wrap.isUpperSignWrapped());
+
+  // The behavior differs if Upper is the Min/SignedMin value.
+  ConstantRange CR1(APInt(8, 42), APInt::getMinValue(8));
+  EXPECT_FALSE(CR1.isWrappedSet());
+  EXPECT_TRUE(CR1.isUpperWrapped());
+
+  ConstantRange CR2(APInt(8, 42), APInt::getSignedMinValue(8));
+  EXPECT_FALSE(CR2.isSignWrappedSet());
+  EXPECT_TRUE(CR2.isUpperSignWrapped());
+}
+
 TEST_F(ConstantRangeTest, Trunc) {
   ConstantRange TFull = Full.truncate(10);
   ConstantRange TEmpty = Empty.truncate(10);
@@ -299,13 +418,163 @@
   LHS = ConstantRange(APInt(32, 4), APInt(32, 2));
   RHS = ConstantRange(APInt(32, 1), APInt(32, 0));
   EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 2)));
- 
+
   // [15, 0) /\ [7, 6) = [15, 0)
   LHS = ConstantRange(APInt(32, 15), APInt(32, 0));
   RHS = ConstantRange(APInt(32, 7), APInt(32, 6));
   EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 15), APInt(32, 0)));
 }
 
+template<typename Fn1, typename Fn2>
+void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 InResultFn) {
+  unsigned Bits = 4;
+  EnumerateTwoConstantRanges(Bits,
+      [=](const ConstantRange &CR1, const ConstantRange &CR2) {
+        // Collect up to three contiguous unsigned ranges. The HaveInterrupt
+        // variables are used determine when we have to switch to the next
+        // range because the previous one ended.
+        APInt Lower1(Bits, 0), Upper1(Bits, 0);
+        APInt Lower2(Bits, 0), Upper2(Bits, 0);
+        APInt Lower3(Bits, 0), Upper3(Bits, 0);
+        bool HaveRange1 = false, HaveInterrupt1 = false;
+        bool HaveRange2 = false, HaveInterrupt2 = false;
+        bool HaveRange3 = false, HaveInterrupt3 = false;
+
+        APInt Num(Bits, 0);
+        for (unsigned I = 0, Limit = 1 << Bits; I < Limit; ++I, ++Num) {
+          if (!InResultFn(CR1, CR2, Num)) {
+            if (HaveRange3)
+              HaveInterrupt3 = true;
+            else if (HaveRange2)
+              HaveInterrupt2 = true;
+            else if (HaveRange1)
+              HaveInterrupt1 = true;
+            continue;
+          }
+
+          if (HaveRange3) {
+            Upper3 = Num;
+          } else if (HaveInterrupt2) {
+            HaveRange3 = true;
+            Lower3 = Upper3 = Num;
+          } else if (HaveRange2) {
+            Upper2 = Num;
+          } else if (HaveInterrupt1) {
+            HaveRange2 = true;
+            Lower2 = Upper2 = Num;
+          } else if (HaveRange1) {
+            Upper1 = Num;
+          } else {
+            HaveRange1 = true;
+            Lower1 = Upper1 = Num;
+          }
+        }
+
+        (void)HaveInterrupt3;
+        assert(!HaveInterrupt3 && "Should have at most three ranges");
+
+        ConstantRange SmallestCR = OpFn(CR1, CR2, ConstantRange::Smallest);
+        ConstantRange UnsignedCR = OpFn(CR1, CR2, ConstantRange::Unsigned);
+        ConstantRange SignedCR = OpFn(CR1, CR2, ConstantRange::Signed);
+
+        if (!HaveRange1) {
+          EXPECT_TRUE(SmallestCR.isEmptySet());
+          EXPECT_TRUE(UnsignedCR.isEmptySet());
+          EXPECT_TRUE(SignedCR.isEmptySet());
+          return;
+        }
+
+        if (!HaveRange2) {
+          if (Lower1 == Upper1 + 1) {
+            EXPECT_TRUE(SmallestCR.isFullSet());
+            EXPECT_TRUE(UnsignedCR.isFullSet());
+            EXPECT_TRUE(SignedCR.isFullSet());
+          } else {
+            ConstantRange Expected(Lower1, Upper1 + 1);
+            EXPECT_EQ(Expected, SmallestCR);
+            EXPECT_EQ(Expected, UnsignedCR);
+            EXPECT_EQ(Expected, SignedCR);
+          }
+          return;
+        }
+
+        ConstantRange Variant1(Bits, /*full*/ true);
+        ConstantRange Variant2(Bits, /*full*/ true);
+        if (!HaveRange3) {
+          // Compute the two possible ways to cover two disjoint ranges.
+          if (Lower1 != Upper2 + 1)
+            Variant1 = ConstantRange(Lower1, Upper2 + 1);
+          if (Lower2 != Upper1 + 1)
+            Variant2 = ConstantRange(Lower2, Upper1 + 1);
+        } else {
+          // If we have three ranges, the first and last one have to be adjacent
+          // to the unsigned domain. It's better to think of this as having two
+          // holes, and we can construct one range using each hole.
+          assert(Lower1.isNullValue() && Upper3.isMaxValue());
+          Variant1 = ConstantRange(Lower2, Upper1 + 1);
+          Variant2 = ConstantRange(Lower3, Upper2 + 1);
+        }
+
+        // Smallest: Smaller set, then any set.
+        if (Variant1.isSizeStrictlySmallerThan(Variant2))
+          EXPECT_EQ(Variant1, SmallestCR);
+        else if (Variant2.isSizeStrictlySmallerThan(Variant1))
+          EXPECT_EQ(Variant2, SmallestCR);
+        else
+          EXPECT_TRUE(Variant1 == SmallestCR || Variant2 == SmallestCR);
+
+        // Unsigned: Non-wrapped set, then smaller set, then any set.
+        bool Variant1Full = Variant1.isFullSet() || Variant1.isWrappedSet();
+        bool Variant2Full = Variant2.isFullSet() || Variant2.isWrappedSet();
+        if (!Variant1Full && Variant2Full)
+          EXPECT_EQ(Variant1, UnsignedCR);
+        else if (Variant1Full && !Variant2Full)
+          EXPECT_EQ(Variant2, UnsignedCR);
+        else if (Variant1.isSizeStrictlySmallerThan(Variant2))
+          EXPECT_EQ(Variant1, UnsignedCR);
+        else if (Variant2.isSizeStrictlySmallerThan(Variant1))
+          EXPECT_EQ(Variant2, UnsignedCR);
+        else
+          EXPECT_TRUE(Variant1 == UnsignedCR || Variant2 == UnsignedCR);
+
+        // Signed: Signed non-wrapped set, then smaller set, then any set.
+        Variant1Full = Variant1.isFullSet() || Variant1.isSignWrappedSet();
+        Variant2Full = Variant2.isFullSet() || Variant2.isSignWrappedSet();
+        if (!Variant1Full && Variant2Full)
+          EXPECT_EQ(Variant1, SignedCR);
+        else if (Variant1Full && !Variant2Full)
+          EXPECT_EQ(Variant2, SignedCR);
+        else if (Variant1.isSizeStrictlySmallerThan(Variant2))
+          EXPECT_EQ(Variant1, SignedCR);
+        else if (Variant2.isSizeStrictlySmallerThan(Variant1))
+          EXPECT_EQ(Variant2, SignedCR);
+        else
+          EXPECT_TRUE(Variant1 == SignedCR || Variant2 == SignedCR);
+      });
+}
+
+TEST_F(ConstantRangeTest, IntersectWithExhaustive) {
+  testBinarySetOperationExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2,
+         ConstantRange::PreferredRangeType Type) {
+        return CR1.intersectWith(CR2, Type);
+      },
+      [](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {
+        return CR1.contains(N) && CR2.contains(N);
+      });
+}
+
+TEST_F(ConstantRangeTest, UnionWithExhaustive) {
+  testBinarySetOperationExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2,
+         ConstantRange::PreferredRangeType Type) {
+        return CR1.unionWith(CR2, Type);
+      },
+      [](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {
+        return CR1.contains(N) || CR2.contains(N);
+      });
+}
+
 TEST_F(ConstantRangeTest, UnionWith) {
   EXPECT_EQ(Wrap.unionWith(One),
             ConstantRange(APInt(16, 0xaaa), APInt(16, 0xb)));
@@ -320,10 +589,10 @@
             ConstantRange(APInt(16, 14), APInt(16, 8)));
   EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(
                                     ConstantRange(APInt(16, 4), APInt(16, 0))),
-              ConstantRange(16));
+            ConstantRange::getFull(16));
   EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(
                                     ConstantRange(APInt(16, 2), APInt(16, 1))),
-              ConstantRange(16));
+            ConstantRange::getFull(16));
 }
 
 TEST_F(ConstantRangeTest, SetDifference) {
@@ -564,9 +833,187 @@
   EXPECT_EQ(Some.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 0x111)));
   EXPECT_EQ(Some.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
   EXPECT_EQ(Wrap.udiv(Wrap), Full);
+
+
+  ConstantRange Zero(APInt(16, 0));
+  EXPECT_EQ(Zero.udiv(One), Zero);
+  EXPECT_EQ(Zero.udiv(Full), Zero);
+
+  EXPECT_EQ(ConstantRange(APInt(16, 0), APInt(16, 99)).udiv(Full),
+            ConstantRange(APInt(16, 0), APInt(16, 99)));
+  EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 99)).udiv(Full),
+            ConstantRange(APInt(16, 0), APInt(16, 99)));
+}
+
+TEST_F(ConstantRangeTest, SDiv) {
+  unsigned Bits = 4;
+  EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
+                                       const ConstantRange &CR2) {
+    // Collect possible results in a bit vector. We store the signed value plus
+    // a bias to make it unsigned.
+    int Bias = 1 << (Bits - 1);
+    BitVector Results(1 << Bits);
+    ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+      ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+        // Division by zero is UB.
+        if (N2 == 0)
+          return;
+
+        // SignedMin / -1 is UB.
+        if (N1.isMinSignedValue() && N2.isAllOnesValue())
+          return;
+
+        APInt N = N1.sdiv(N2);
+        Results.set(N.getSExtValue() + Bias);
+      });
+    });
+
+    ConstantRange CR = CR1.sdiv(CR2);
+    if (Results.none()) {
+      EXPECT_TRUE(CR.isEmptySet());
+      return;
+    }
+
+    // If there is a non-full signed envelope, that should be the result.
+    APInt SMin(Bits, Results.find_first() - Bias);
+    APInt SMax(Bits, Results.find_last() - Bias);
+    ConstantRange Envelope = ConstantRange::getNonEmpty(SMin, SMax + 1);
+    if (!Envelope.isFullSet()) {
+      EXPECT_EQ(Envelope, CR);
+      return;
+    }
+
+    // If the signed envelope is a full set, try to find a smaller sign wrapped
+    // set that is separated in negative and positive components (or one which
+    // can also additionally contain zero).
+    int LastNeg = Results.find_last_in(0, Bias) - Bias;
+    int LastPos = Results.find_next(Bias) - Bias;
+    if (Results[Bias]) {
+      if (LastNeg == -1)
+        ++LastNeg;
+      else if (LastPos == 1)
+        --LastPos;
+    }
+
+    APInt WMax(Bits, LastNeg);
+    APInt WMin(Bits, LastPos);
+    ConstantRange Wrapped = ConstantRange::getNonEmpty(WMin, WMax + 1);
+    EXPECT_EQ(Wrapped, CR);
+  });
+}
+
+TEST_F(ConstantRangeTest, URem) {
+  EXPECT_EQ(Full.urem(Empty), Empty);
+  EXPECT_EQ(Empty.urem(Full), Empty);
+  // urem by zero is poison.
+  EXPECT_EQ(Full.urem(ConstantRange(APInt(16, 0))), Empty);
+  // urem by full range doesn't contain MaxValue.
+  EXPECT_EQ(Full.urem(Full), ConstantRange(APInt(16, 0), APInt(16, 0xffff)));
+  // urem is upper bounded by maximum RHS minus one.
+  EXPECT_EQ(Full.urem(ConstantRange(APInt(16, 0), APInt(16, 123))),
+            ConstantRange(APInt(16, 0), APInt(16, 122)));
+  // urem is upper bounded by maximum LHS.
+  EXPECT_EQ(ConstantRange(APInt(16, 0), APInt(16, 123)).urem(Full),
+            ConstantRange(APInt(16, 0), APInt(16, 123)));
+  // If the LHS is always lower than the RHS, the result is the LHS.
+  EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 20))
+                .urem(ConstantRange(APInt(16, 20), APInt(16, 30))),
+            ConstantRange(APInt(16, 10), APInt(16, 20)));
+  // It has to be strictly lower, otherwise the top value may wrap to zero.
+  EXPECT_EQ(ConstantRange(APInt(16, 10), APInt(16, 20))
+                .urem(ConstantRange(APInt(16, 19), APInt(16, 30))),
+            ConstantRange(APInt(16, 0), APInt(16, 20)));
+  // [12, 14] % 10 is [2, 4], but we conservatively compute [0, 9].
+  EXPECT_EQ(ConstantRange(APInt(16, 12), APInt(16, 15))
+                .urem(ConstantRange(APInt(16, 10))),
+            ConstantRange(APInt(16, 0), APInt(16, 10)));
+
+  TestUnsignedBinOpExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.urem(CR2);
+      },
+      [](const APInt &N1, const APInt &N2) {
+        return N1.urem(N2);
+      },
+      /* SkipZeroRHS */ true, /* CorrectnessOnly */ true);
+}
+
+TEST_F(ConstantRangeTest, SRem) {
+  EXPECT_EQ(Full.srem(Empty), Empty);
+  EXPECT_EQ(Empty.srem(Full), Empty);
+  // srem by zero is UB.
+  EXPECT_EQ(Full.srem(ConstantRange(APInt(16, 0))), Empty);
+  // srem by full range doesn't contain SignedMinValue.
+  EXPECT_EQ(Full.srem(Full), ConstantRange(APInt::getSignedMinValue(16) + 1,
+                                           APInt::getSignedMinValue(16)));
+
+  ConstantRange PosMod(APInt(16, 10), APInt(16, 21));  // [10, 20]
+  ConstantRange NegMod(APInt(16, -20), APInt(16, -9)); // [-20, -10]
+  ConstantRange IntMinMod(APInt::getSignedMinValue(16));
+
+  ConstantRange Expected(16, true);
+
+  // srem is bounded by abs(RHS) minus one.
+  ConstantRange PosLargeLHS(APInt(16, 0), APInt(16, 41));
+  Expected = ConstantRange(APInt(16, 0), APInt(16, 20));
+  EXPECT_EQ(PosLargeLHS.srem(PosMod), Expected);
+  EXPECT_EQ(PosLargeLHS.srem(NegMod), Expected);
+  ConstantRange NegLargeLHS(APInt(16, -40), APInt(16, 1));
+  Expected = ConstantRange(APInt(16, -19), APInt(16, 1));
+  EXPECT_EQ(NegLargeLHS.srem(PosMod), Expected);
+  EXPECT_EQ(NegLargeLHS.srem(NegMod), Expected);
+  ConstantRange PosNegLargeLHS(APInt(16, -32), APInt(16, 38));
+  Expected = ConstantRange(APInt(16, -19), APInt(16, 20));
+  EXPECT_EQ(PosNegLargeLHS.srem(PosMod), Expected);
+  EXPECT_EQ(PosNegLargeLHS.srem(NegMod), Expected);
+
+  // srem is bounded by LHS.
+  ConstantRange PosLHS(APInt(16, 0), APInt(16, 16));
+  EXPECT_EQ(PosLHS.srem(PosMod), PosLHS);
+  EXPECT_EQ(PosLHS.srem(NegMod), PosLHS);
+  EXPECT_EQ(PosLHS.srem(IntMinMod), PosLHS);
+  ConstantRange NegLHS(APInt(16, -15), APInt(16, 1));
+  EXPECT_EQ(NegLHS.srem(PosMod), NegLHS);
+  EXPECT_EQ(NegLHS.srem(NegMod), NegLHS);
+  EXPECT_EQ(NegLHS.srem(IntMinMod), NegLHS);
+  ConstantRange PosNegLHS(APInt(16, -12), APInt(16, 18));
+  EXPECT_EQ(PosNegLHS.srem(PosMod), PosNegLHS);
+  EXPECT_EQ(PosNegLHS.srem(NegMod), PosNegLHS);
+  EXPECT_EQ(PosNegLHS.srem(IntMinMod), PosNegLHS);
+
+  // srem is LHS if it is smaller than RHS.
+  ConstantRange PosSmallLHS(APInt(16, 3), APInt(16, 8));
+  EXPECT_EQ(PosSmallLHS.srem(PosMod), PosSmallLHS);
+  EXPECT_EQ(PosSmallLHS.srem(NegMod), PosSmallLHS);
+  EXPECT_EQ(PosSmallLHS.srem(IntMinMod), PosSmallLHS);
+  ConstantRange NegSmallLHS(APInt(16, -7), APInt(16, -2));
+  EXPECT_EQ(NegSmallLHS.srem(PosMod), NegSmallLHS);
+  EXPECT_EQ(NegSmallLHS.srem(NegMod), NegSmallLHS);
+  EXPECT_EQ(NegSmallLHS.srem(IntMinMod), NegSmallLHS);
+  ConstantRange PosNegSmallLHS(APInt(16, -3), APInt(16, 8));
+  EXPECT_EQ(PosNegSmallLHS.srem(PosMod), PosNegSmallLHS);
+  EXPECT_EQ(PosNegSmallLHS.srem(NegMod), PosNegSmallLHS);
+  EXPECT_EQ(PosNegSmallLHS.srem(IntMinMod), PosNegSmallLHS);
+
+  // Example of a suboptimal result:
+  // [12, 14] srem 10 is [2, 4], but we conservatively compute [0, 9].
+  EXPECT_EQ(ConstantRange(APInt(16, 12), APInt(16, 15))
+                .srem(ConstantRange(APInt(16, 10))),
+            ConstantRange(APInt(16, 0), APInt(16, 10)));
+
+  TestSignedBinOpExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.srem(CR2);
+      },
+      [](const APInt &N1, const APInt &N2) {
+        return N1.srem(N2);
+      },
+      /* SkipZeroRHS */ true, /* CorrectnessOnly */ true);
 }
 
 TEST_F(ConstantRangeTest, Shl) {
+  ConstantRange Some2(APInt(16, 0xfff), APInt(16, 0x8000));
+  ConstantRange WrapNullMax(APInt(16, 0x1), APInt(16, 0x0));
   EXPECT_EQ(Full.shl(Full), Full);
   EXPECT_EQ(Full.shl(Empty), Empty);
   EXPECT_EQ(Full.shl(One), Full);    // TODO: [0, (-1 << 0xa) + 1)
@@ -583,6 +1030,10 @@
   EXPECT_EQ(Some.shl(Some), Full);   // TODO: [0xa << 0xa, 0xfc01)
   EXPECT_EQ(Some.shl(Wrap), Full);   // TODO: [0xa, 0x7ff << 0x5 + 1)
   EXPECT_EQ(Wrap.shl(Wrap), Full);
+  EXPECT_EQ(
+      Some2.shl(ConstantRange(APInt(16, 0x1))),
+      ConstantRange(APInt(16, 0xfff << 0x1), APInt(16, 0x7fff << 0x1) + 1));
+  EXPECT_EQ(One.shl(WrapNullMax), Full);
 }
 
 TEST_F(ConstantRangeTest, Lshr) {
@@ -710,12 +1161,6 @@
 
     EXPECT_FALSE(NSWRegion.isEmptySet());
 
-    auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
-        Instruction::Add, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
-
-    EXPECT_FALSE(NoWrapRegion.isEmptySet());
-    EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
-
     for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
          ++I) {
       bool Overflow = false;
@@ -729,17 +1174,6 @@
       (void)I.sadd_ov(C, Overflow);
       EXPECT_FALSE(Overflow);
     }
-
-    for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
-         ++I) {
-      bool Overflow = false;
-
-      (void)I.sadd_ov(C, Overflow);
-      EXPECT_FALSE(Overflow);
-
-      (void)I.uadd_ov(C, Overflow);
-      EXPECT_FALSE(Overflow);
-    }
   }
 
   for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {
@@ -755,12 +1189,6 @@
 
     EXPECT_FALSE(NSWRegion.isEmptySet());
 
-    auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
-        Instruction::Sub, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
-
-    EXPECT_FALSE(NoWrapRegion.isEmptySet());
-    EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
-
     for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
          ++I) {
       bool Overflow = false;
@@ -774,17 +1202,6 @@
       (void)I.ssub_ov(C, Overflow);
       EXPECT_FALSE(Overflow);
     }
-
-    for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
-         ++I) {
-      bool Overflow = false;
-
-      (void)I.ssub_ov(C, Overflow);
-      EXPECT_FALSE(Overflow);
-
-      (void)I.usub_ov(C, Overflow);
-      EXPECT_FALSE(Overflow);
-    }
   }
 
   auto NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
@@ -811,32 +1228,14 @@
   EXPECT_TRUE(NUWForAllValues.isSingleElement() &&
               NUWForAllValues.getSingleElement()->isMaxValue());
 
-  auto NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
-      Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
-      OBO::NoUnsignedWrap | OBO::NoSignedWrap);
-  EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
-              NUWAndNSWForAllValues.getSingleElement()->isMinValue());
-
-  NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
-      Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),
-      OBO::NoUnsignedWrap | OBO::NoSignedWrap);
-  EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
-              NUWAndNSWForAllValues.getSingleElement()->isMaxValue());
-
   EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
       Instruction::Add, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
   EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
       Instruction::Add, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
   EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
-      Instruction::Add, APInt(32, 0),
-      OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
-  EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
       Instruction::Sub, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
   EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
       Instruction::Sub, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
-  EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
-      Instruction::Sub, APInt(32, 0),
-      OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
 
   ConstantRange OneToFive(APInt(32, 1), APInt(32, 6));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -846,10 +1245,6 @@
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Add, OneToFive, OBO::NoUnsignedWrap),
             ConstantRange(APInt::getMinValue(32), APInt::getMinValue(32) - 5));
-  EXPECT_EQ(
-      ConstantRange::makeGuaranteedNoWrapRegion(
-          Instruction::Add, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-      ConstantRange(APInt::getMinValue(32), APInt::getSignedMaxValue(32) - 4));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Sub, OneToFive, OBO::NoSignedWrap),
             ConstantRange(APInt::getSignedMinValue(32) + 5,
@@ -857,10 +1252,6 @@
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Sub, OneToFive, OBO::NoUnsignedWrap),
             ConstantRange(APInt::getMinValue(32) + 5, APInt::getMinValue(32)));
-  EXPECT_EQ(
-      ConstantRange::makeGuaranteedNoWrapRegion(
-          Instruction::Sub, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-      ConstantRange(APInt::getMinValue(32) + 5, APInt::getSignedMinValue(32)));
 
   ConstantRange MinusFiveToMinusTwo(APInt(32, -5), APInt(32, -1));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -871,10 +1262,6 @@
                 Instruction::Add, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
             ConstantRange(APInt(32, 0), APInt(32, 2)));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
-                Instruction::Add, MinusFiveToMinusTwo,
-                OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-            ConstantRange(APInt(32, 0), APInt(32, 2)));
-  EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Sub, MinusFiveToMinusTwo, OBO::NoSignedWrap),
             ConstantRange(APInt::getSignedMinValue(32),
                           APInt::getSignedMaxValue(32) - 4));
@@ -882,11 +1269,6 @@
                 Instruction::Sub, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
             ConstantRange(APInt::getMaxValue(32) - 1,
                           APInt::getMinValue(32)));
-  EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
-                Instruction::Sub, MinusFiveToMinusTwo,
-                OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-            ConstantRange(APInt::getMaxValue(32) - 1,
-                          APInt::getMinValue(32)));
 
   ConstantRange MinusOneToOne(APInt(32, -1), APInt(32, 2));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -897,10 +1279,6 @@
                 Instruction::Add, MinusOneToOne, OBO::NoUnsignedWrap),
             ConstantRange(APInt(32, 0), APInt(32, 1)));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
-                Instruction::Add, MinusOneToOne,
-                OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-            ConstantRange(APInt(32, 0), APInt(32, 1)));
-  EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Sub, MinusOneToOne, OBO::NoSignedWrap),
             ConstantRange(APInt::getSignedMinValue(32) + 1,
                           APInt::getSignedMinValue(32) - 1));
@@ -908,11 +1286,6 @@
                 Instruction::Sub, MinusOneToOne, OBO::NoUnsignedWrap),
             ConstantRange(APInt::getMaxValue(32),
                           APInt::getMinValue(32)));
-  EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
-                Instruction::Sub, MinusOneToOne,
-                OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-            ConstantRange(APInt::getMaxValue(32),
-                          APInt::getMinValue(32)));
 
   ConstantRange One(APInt(32, 1), APInt(32, 2));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -922,10 +1295,6 @@
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Add, One, OBO::NoUnsignedWrap),
             ConstantRange(APInt::getMinValue(32), APInt::getMaxValue(32)));
-  EXPECT_EQ(
-      ConstantRange::makeGuaranteedNoWrapRegion(
-          Instruction::Add, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-      ConstantRange(APInt(32, 0), APInt::getSignedMaxValue(32)));
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Sub, One, OBO::NoSignedWrap),
             ConstantRange(APInt::getSignedMinValue(32) + 1,
@@ -933,10 +1302,84 @@
   EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
                 Instruction::Sub, One, OBO::NoUnsignedWrap),
             ConstantRange(APInt::getMinValue(32) + 1, APInt::getMinValue(32)));
-  EXPECT_EQ(
-      ConstantRange::makeGuaranteedNoWrapRegion(
-          Instruction::Sub, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
-      ConstantRange(APInt::getMinValue(32) + 1, APInt::getSignedMinValue(32)));
+}
+
+template<typename Fn>
+void TestNoWrapRegionExhaustive(Instruction::BinaryOps BinOp,
+                                unsigned NoWrapKind, Fn OverflowFn) {
+  // When using 4 bits this test needs ~3s on a debug build.
+  unsigned Bits = 3;
+  EnumerateTwoConstantRanges(Bits,
+      [&](const ConstantRange &CR1, const ConstantRange &CR2) {
+        if (CR2.isEmptySet())
+          return;
+
+        ConstantRange NoWrap =
+            ConstantRange::makeGuaranteedNoWrapRegion(BinOp, CR2, NoWrapKind);
+        ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+          bool NoOverflow = true;
+          bool Overflow = true;
+          ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+            if (OverflowFn(N1, N2))
+              NoOverflow = false;
+            else
+              Overflow = false;
+          });
+          EXPECT_EQ(NoOverflow, NoWrap.contains(N1));
+
+          // The no-wrap range is exact for single-element ranges.
+          if (CR2.isSingleElement()) {
+            EXPECT_EQ(Overflow, !NoWrap.contains(N1));
+          }
+        });
+      });
+}
+
+// Show that makeGuaranteedNoWrapRegion() is maximal, and for single-element
+// ranges also exact.
+TEST(ConstantRange, NoWrapRegionExhaustive) {
+  TestNoWrapRegionExhaustive(
+      Instruction::Add, OverflowingBinaryOperator::NoUnsignedWrap,
+      [](const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.uadd_ov(N2, Overflow);
+        return Overflow;
+      });
+  TestNoWrapRegionExhaustive(
+      Instruction::Add, OverflowingBinaryOperator::NoSignedWrap,
+      [](const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.sadd_ov(N2, Overflow);
+        return Overflow;
+      });
+  TestNoWrapRegionExhaustive(
+      Instruction::Sub, OverflowingBinaryOperator::NoUnsignedWrap,
+      [](const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.usub_ov(N2, Overflow);
+        return Overflow;
+      });
+  TestNoWrapRegionExhaustive(
+      Instruction::Sub, OverflowingBinaryOperator::NoSignedWrap,
+      [](const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.ssub_ov(N2, Overflow);
+        return Overflow;
+      });
+  TestNoWrapRegionExhaustive(
+      Instruction::Mul, OverflowingBinaryOperator::NoUnsignedWrap,
+      [](const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.umul_ov(N2, Overflow);
+        return Overflow;
+      });
+  TestNoWrapRegionExhaustive(
+      Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap,
+      [](const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.smul_ov(N2, Overflow);
+        return Overflow;
+      });
 }
 
 TEST(ConstantRange, GetEquivalentICmp) {
@@ -1060,26 +1503,6 @@
   }
 }
 
-TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedAndSignedSingleValue) {
-  typedef OverflowingBinaryOperator OBO;
-
-  for (uint64_t I = std::numeric_limits<uint8_t>::min();
-       I <= std::numeric_limits<uint8_t>::max(); I++) {
-    auto Range = ConstantRange::makeGuaranteedNoWrapRegion(
-        Instruction::Mul, ConstantRange(APInt(8, I), APInt(8, I + 1)),
-        OBO::NoUnsignedWrap | OBO::NoSignedWrap);
-
-    for (uint64_t V = std::numeric_limits<uint8_t>::min();
-         V <= std::numeric_limits<uint8_t>::max(); V++) {
-      bool UOverflow;
-      (void)APInt(8, I).umul_ov(APInt(8, V), UOverflow);
-      bool SOverflow;
-      (void)APInt(8, I).smul_ov(APInt(8, V), SOverflow);
-      EXPECT_EQ(!(UOverflow || SOverflow), Range.contains(APInt(8, V)));
-    }
-  }
-}
-
 TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedRange) {
   typedef OverflowingBinaryOperator OBO;
 
@@ -1120,4 +1543,455 @@
   }
 }
 
+#define EXPECT_MAY_OVERFLOW(op) \
+  EXPECT_EQ(ConstantRange::OverflowResult::MayOverflow, (op))
+#define EXPECT_ALWAYS_OVERFLOWS_LOW(op) \
+  EXPECT_EQ(ConstantRange::OverflowResult::AlwaysOverflowsLow, (op))
+#define EXPECT_ALWAYS_OVERFLOWS_HIGH(op) \
+  EXPECT_EQ(ConstantRange::OverflowResult::AlwaysOverflowsHigh, (op))
+#define EXPECT_NEVER_OVERFLOWS(op) \
+  EXPECT_EQ(ConstantRange::OverflowResult::NeverOverflows, (op))
+
+TEST_F(ConstantRangeTest, UnsignedAddOverflow) {
+  // Ill-defined - may overflow is a conservative result.
+  EXPECT_MAY_OVERFLOW(Some.unsignedAddMayOverflow(Empty));
+  EXPECT_MAY_OVERFLOW(Empty.unsignedAddMayOverflow(Some));
+
+  // Never overflow despite one full/wrap set.
+  ConstantRange Zero(APInt::getNullValue(16));
+  EXPECT_NEVER_OVERFLOWS(Full.unsignedAddMayOverflow(Zero));
+  EXPECT_NEVER_OVERFLOWS(Wrap.unsignedAddMayOverflow(Zero));
+  EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Full));
+  EXPECT_NEVER_OVERFLOWS(Zero.unsignedAddMayOverflow(Wrap));
+
+  // But usually full/wrap always may overflow.
+  EXPECT_MAY_OVERFLOW(Full.unsignedAddMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(Wrap.unsignedAddMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Full));
+  EXPECT_MAY_OVERFLOW(One.unsignedAddMayOverflow(Wrap));
+
+  ConstantRange A(APInt(16, 0xfd00), APInt(16, 0xfe00));
+  ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
+  ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
+  EXPECT_NEVER_OVERFLOWS(A.unsignedAddMayOverflow(B1));
+  EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(B2));
+  EXPECT_NEVER_OVERFLOWS(B1.unsignedAddMayOverflow(A));
+  EXPECT_MAY_OVERFLOW(B2.unsignedAddMayOverflow(A));
+
+  ConstantRange C1(APInt(16, 0x0299), APInt(16, 0x0400));
+  ConstantRange C2(APInt(16, 0x0300), APInt(16, 0x0400));
+  EXPECT_MAY_OVERFLOW(A.unsignedAddMayOverflow(C1));
+  EXPECT_ALWAYS_OVERFLOWS_HIGH(A.unsignedAddMayOverflow(C2));
+  EXPECT_MAY_OVERFLOW(C1.unsignedAddMayOverflow(A));
+  EXPECT_ALWAYS_OVERFLOWS_HIGH(C2.unsignedAddMayOverflow(A));
+}
+
+TEST_F(ConstantRangeTest, UnsignedSubOverflow) {
+  // Ill-defined - may overflow is a conservative result.
+  EXPECT_MAY_OVERFLOW(Some.unsignedSubMayOverflow(Empty));
+  EXPECT_MAY_OVERFLOW(Empty.unsignedSubMayOverflow(Some));
+
+  // Never overflow despite one full/wrap set.
+  ConstantRange Zero(APInt::getNullValue(16));
+  ConstantRange Max(APInt::getAllOnesValue(16));
+  EXPECT_NEVER_OVERFLOWS(Full.unsignedSubMayOverflow(Zero));
+  EXPECT_NEVER_OVERFLOWS(Wrap.unsignedSubMayOverflow(Zero));
+  EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Full));
+  EXPECT_NEVER_OVERFLOWS(Max.unsignedSubMayOverflow(Wrap));
+
+  // But usually full/wrap always may overflow.
+  EXPECT_MAY_OVERFLOW(Full.unsignedSubMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(Wrap.unsignedSubMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Full));
+  EXPECT_MAY_OVERFLOW(One.unsignedSubMayOverflow(Wrap));
+
+  ConstantRange A(APInt(16, 0x0000), APInt(16, 0x0100));
+  ConstantRange B(APInt(16, 0x0100), APInt(16, 0x0200));
+  EXPECT_NEVER_OVERFLOWS(B.unsignedSubMayOverflow(A));
+  EXPECT_ALWAYS_OVERFLOWS_LOW(A.unsignedSubMayOverflow(B));
+
+  ConstantRange A1(APInt(16, 0x0000), APInt(16, 0x0101));
+  ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
+  EXPECT_NEVER_OVERFLOWS(B1.unsignedSubMayOverflow(A1));
+  EXPECT_MAY_OVERFLOW(A1.unsignedSubMayOverflow(B1));
+
+  ConstantRange A2(APInt(16, 0x0000), APInt(16, 0x0102));
+  ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
+  EXPECT_MAY_OVERFLOW(B2.unsignedSubMayOverflow(A2));
+  EXPECT_MAY_OVERFLOW(A2.unsignedSubMayOverflow(B2));
+}
+
+TEST_F(ConstantRangeTest, SignedAddOverflow) {
+  // Ill-defined - may overflow is a conservative result.
+  EXPECT_MAY_OVERFLOW(Some.signedAddMayOverflow(Empty));
+  EXPECT_MAY_OVERFLOW(Empty.signedAddMayOverflow(Some));
+
+  // Never overflow despite one full/wrap set.
+  ConstantRange Zero(APInt::getNullValue(16));
+  EXPECT_NEVER_OVERFLOWS(Full.signedAddMayOverflow(Zero));
+  EXPECT_NEVER_OVERFLOWS(Wrap.signedAddMayOverflow(Zero));
+  EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Full));
+  EXPECT_NEVER_OVERFLOWS(Zero.signedAddMayOverflow(Wrap));
+
+  // But usually full/wrap always may overflow.
+  EXPECT_MAY_OVERFLOW(Full.signedAddMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(Wrap.signedAddMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Full));
+  EXPECT_MAY_OVERFLOW(One.signedAddMayOverflow(Wrap));
+
+  ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));
+  ConstantRange B1(APInt(16, 0x0100), APInt(16, 0x0201));
+  ConstantRange B2(APInt(16, 0x0100), APInt(16, 0x0202));
+  EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B1));
+  EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B2));
+  ConstantRange B3(APInt(16, 0x8000), APInt(16, 0x0201));
+  ConstantRange B4(APInt(16, 0x8000), APInt(16, 0x0202));
+  EXPECT_NEVER_OVERFLOWS(A.signedAddMayOverflow(B3));
+  EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B4));
+  ConstantRange B5(APInt(16, 0x0299), APInt(16, 0x0400));
+  ConstantRange B6(APInt(16, 0x0300), APInt(16, 0x0400));
+  EXPECT_MAY_OVERFLOW(A.signedAddMayOverflow(B5));
+  EXPECT_ALWAYS_OVERFLOWS_HIGH(A.signedAddMayOverflow(B6));
+
+  ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));
+  ConstantRange D1(APInt(16, 0xfe00), APInt(16, 0xff00));
+  ConstantRange D2(APInt(16, 0xfd99), APInt(16, 0xff00));
+  EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D1));
+  EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D2));
+  ConstantRange D3(APInt(16, 0xfe00), APInt(16, 0x8000));
+  ConstantRange D4(APInt(16, 0xfd99), APInt(16, 0x8000));
+  EXPECT_NEVER_OVERFLOWS(C.signedAddMayOverflow(D3));
+  EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D4));
+  ConstantRange D5(APInt(16, 0xfc00), APInt(16, 0xfd02));
+  ConstantRange D6(APInt(16, 0xfc00), APInt(16, 0xfd01));
+  EXPECT_MAY_OVERFLOW(C.signedAddMayOverflow(D5));
+  EXPECT_ALWAYS_OVERFLOWS_LOW(C.signedAddMayOverflow(D6));
+
+  ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));
+  EXPECT_NEVER_OVERFLOWS(E.signedAddMayOverflow(E));
+  ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7000));
+  EXPECT_MAY_OVERFLOW(F.signedAddMayOverflow(F));
+}
+
+TEST_F(ConstantRangeTest, SignedSubOverflow) {
+  // Ill-defined - may overflow is a conservative result.
+  EXPECT_MAY_OVERFLOW(Some.signedSubMayOverflow(Empty));
+  EXPECT_MAY_OVERFLOW(Empty.signedSubMayOverflow(Some));
+
+  // Never overflow despite one full/wrap set.
+  ConstantRange Zero(APInt::getNullValue(16));
+  EXPECT_NEVER_OVERFLOWS(Full.signedSubMayOverflow(Zero));
+  EXPECT_NEVER_OVERFLOWS(Wrap.signedSubMayOverflow(Zero));
+
+  // But usually full/wrap always may overflow.
+  EXPECT_MAY_OVERFLOW(Full.signedSubMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(Wrap.signedSubMayOverflow(One));
+  EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Full));
+  EXPECT_MAY_OVERFLOW(One.signedSubMayOverflow(Wrap));
+
+  ConstantRange A(APInt(16, 0x7d00), APInt(16, 0x7e00));
+  ConstantRange B1(APInt(16, 0xfe00), APInt(16, 0xff00));
+  ConstantRange B2(APInt(16, 0xfd99), APInt(16, 0xff00));
+  EXPECT_NEVER_OVERFLOWS(A.signedSubMayOverflow(B1));
+  EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B2));
+  ConstantRange B3(APInt(16, 0xfc00), APInt(16, 0xfd02));
+  ConstantRange B4(APInt(16, 0xfc00), APInt(16, 0xfd01));
+  EXPECT_MAY_OVERFLOW(A.signedSubMayOverflow(B3));
+  EXPECT_ALWAYS_OVERFLOWS_HIGH(A.signedSubMayOverflow(B4));
+
+  ConstantRange C(APInt(16, 0x8200), APInt(16, 0x8300));
+  ConstantRange D1(APInt(16, 0x0100), APInt(16, 0x0201));
+  ConstantRange D2(APInt(16, 0x0100), APInt(16, 0x0202));
+  EXPECT_NEVER_OVERFLOWS(C.signedSubMayOverflow(D1));
+  EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D2));
+  ConstantRange D3(APInt(16, 0x0299), APInt(16, 0x0400));
+  ConstantRange D4(APInt(16, 0x0300), APInt(16, 0x0400));
+  EXPECT_MAY_OVERFLOW(C.signedSubMayOverflow(D3));
+  EXPECT_ALWAYS_OVERFLOWS_LOW(C.signedSubMayOverflow(D4));
+
+  ConstantRange E(APInt(16, 0xff00), APInt(16, 0x0100));
+  EXPECT_NEVER_OVERFLOWS(E.signedSubMayOverflow(E));
+  ConstantRange F(APInt(16, 0xf000), APInt(16, 0x7001));
+  EXPECT_MAY_OVERFLOW(F.signedSubMayOverflow(F));
+}
+
+template<typename Fn1, typename Fn2>
+static void TestOverflowExhaustive(Fn1 OverflowFn, Fn2 MayOverflowFn) {
+  // Constant range overflow checks are tested exhaustively on 4-bit numbers.
+  unsigned Bits = 4;
+  EnumerateTwoConstantRanges(Bits, [=](const ConstantRange &CR1,
+                                       const ConstantRange &CR2) {
+    // Loop over all N1 in CR1 and N2 in CR2 and check whether any of the
+    // operations have overflow / have no overflow.
+    bool RangeHasOverflowLow = false;
+    bool RangeHasOverflowHigh = false;
+    bool RangeHasNoOverflow = false;
+    ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+      ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+        bool IsOverflowHigh;
+        if (!OverflowFn(IsOverflowHigh, N1, N2)) {
+          RangeHasNoOverflow = true;
+          return;
+        }
+
+        if (IsOverflowHigh)
+          RangeHasOverflowHigh = true;
+        else
+          RangeHasOverflowLow = true;
+      });
+    });
+
+    ConstantRange::OverflowResult OR = MayOverflowFn(CR1, CR2);
+    switch (OR) {
+    case ConstantRange::OverflowResult::AlwaysOverflowsLow:
+      EXPECT_TRUE(RangeHasOverflowLow);
+      EXPECT_FALSE(RangeHasOverflowHigh);
+      EXPECT_FALSE(RangeHasNoOverflow);
+      break;
+    case ConstantRange::OverflowResult::AlwaysOverflowsHigh:
+      EXPECT_TRUE(RangeHasOverflowHigh);
+      EXPECT_FALSE(RangeHasOverflowLow);
+      EXPECT_FALSE(RangeHasNoOverflow);
+      break;
+    case ConstantRange::OverflowResult::NeverOverflows:
+      EXPECT_FALSE(RangeHasOverflowLow);
+      EXPECT_FALSE(RangeHasOverflowHigh);
+      EXPECT_TRUE(RangeHasNoOverflow);
+      break;
+    case ConstantRange::OverflowResult::MayOverflow:
+      // We return MayOverflow for empty sets as a conservative result,
+      // but of course neither the RangeHasOverflow nor the
+      // RangeHasNoOverflow flags will be set.
+      if (CR1.isEmptySet() || CR2.isEmptySet())
+        break;
+
+      EXPECT_TRUE(RangeHasOverflowLow || RangeHasOverflowHigh);
+      EXPECT_TRUE(RangeHasNoOverflow);
+      break;
+    }
+  });
+}
+
+TEST_F(ConstantRangeTest, UnsignedAddOverflowExhaustive) {
+  TestOverflowExhaustive(
+      [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.uadd_ov(N2, Overflow);
+        IsOverflowHigh = true;
+        return Overflow;
+      },
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.unsignedAddMayOverflow(CR2);
+      });
+}
+
+TEST_F(ConstantRangeTest, UnsignedSubOverflowExhaustive) {
+  TestOverflowExhaustive(
+      [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.usub_ov(N2, Overflow);
+        IsOverflowHigh = false;
+        return Overflow;
+      },
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.unsignedSubMayOverflow(CR2);
+      });
+}
+
+TEST_F(ConstantRangeTest, UnsignedMulOverflowExhaustive) {
+  TestOverflowExhaustive(
+      [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.umul_ov(N2, Overflow);
+        IsOverflowHigh = true;
+        return Overflow;
+      },
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.unsignedMulMayOverflow(CR2);
+      });
+}
+
+TEST_F(ConstantRangeTest, SignedAddOverflowExhaustive) {
+  TestOverflowExhaustive(
+      [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.sadd_ov(N2, Overflow);
+        IsOverflowHigh = N1.isNonNegative();
+        return Overflow;
+      },
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.signedAddMayOverflow(CR2);
+      });
+}
+
+TEST_F(ConstantRangeTest, SignedSubOverflowExhaustive) {
+  TestOverflowExhaustive(
+      [](bool &IsOverflowHigh, const APInt &N1, const APInt &N2) {
+        bool Overflow;
+        (void) N1.ssub_ov(N2, Overflow);
+        IsOverflowHigh = N1.isNonNegative();
+        return Overflow;
+      },
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.signedSubMayOverflow(CR2);
+      });
+}
+
+TEST_F(ConstantRangeTest, FromKnownBits) {
+  KnownBits Unknown(16);
+  EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/false));
+  EXPECT_EQ(Full, ConstantRange::fromKnownBits(Unknown, /*signed*/true));
+
+  // .10..01. -> unsigned 01000010 (66)  to 11011011 (219)
+  //          -> signed   11000010 (194) to 01011011 (91)
+  KnownBits Known(8);
+  Known.Zero = 36;
+  Known.One = 66;
+  ConstantRange Unsigned(APInt(8, 66), APInt(8, 219 + 1));
+  ConstantRange Signed(APInt(8, 194), APInt(8, 91 + 1));
+  EXPECT_EQ(Unsigned, ConstantRange::fromKnownBits(Known, /*signed*/false));
+  EXPECT_EQ(Signed, ConstantRange::fromKnownBits(Known, /*signed*/true));
+
+  // 1.10.10. -> 10100100 (164) to 11101101 (237)
+  Known.Zero = 18;
+  Known.One = 164;
+  ConstantRange CR1(APInt(8, 164), APInt(8, 237 + 1));
+  EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/false));
+  EXPECT_EQ(CR1, ConstantRange::fromKnownBits(Known, /*signed*/true));
+
+  // 01.0.1.0 -> 01000100 (68) to 01101110 (110)
+  Known.Zero = 145;
+  Known.One = 68;
+  ConstantRange CR2(APInt(8, 68), APInt(8, 110 + 1));
+  EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/false));
+  EXPECT_EQ(CR2, ConstantRange::fromKnownBits(Known, /*signed*/true));
+}
+
+TEST_F(ConstantRangeTest, FromKnownBitsExhaustive) {
+  unsigned Bits = 4;
+  unsigned Max = 1 << Bits;
+  KnownBits Known(Bits);
+  for (unsigned Zero = 0; Zero < Max; ++Zero) {
+    for (unsigned One = 0; One < Max; ++One) {
+      Known.Zero = Zero;
+      Known.One = One;
+      if (Known.hasConflict() || Known.isUnknown())
+        continue;
+
+      APInt MinUnsigned = APInt::getMaxValue(Bits);
+      APInt MaxUnsigned = APInt::getMinValue(Bits);
+      APInt MinSigned = APInt::getSignedMaxValue(Bits);
+      APInt MaxSigned = APInt::getSignedMinValue(Bits);
+      for (unsigned N = 0; N < Max; ++N) {
+        APInt Num(Bits, N);
+        if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0)
+          continue;
+
+        if (Num.ult(MinUnsigned)) MinUnsigned = Num;
+        if (Num.ugt(MaxUnsigned)) MaxUnsigned = Num;
+        if (Num.slt(MinSigned)) MinSigned = Num;
+        if (Num.sgt(MaxSigned)) MaxSigned = Num;
+      }
+
+      ConstantRange UnsignedCR(MinUnsigned, MaxUnsigned + 1);
+      ConstantRange SignedCR(MinSigned, MaxSigned + 1);
+      EXPECT_EQ(UnsignedCR, ConstantRange::fromKnownBits(Known, false));
+      EXPECT_EQ(SignedCR, ConstantRange::fromKnownBits(Known, true));
+    }
+  }
+}
+
+TEST_F(ConstantRangeTest, Negative) {
+  // All elements in an empty set (of which there are none) are both negative
+  // and non-negative. Empty & full sets checked explicitly for clarity, but
+  // they are also covered by the exhaustive test below.
+  EXPECT_TRUE(Empty.isAllNegative());
+  EXPECT_TRUE(Empty.isAllNonNegative());
+  EXPECT_FALSE(Full.isAllNegative());
+  EXPECT_FALSE(Full.isAllNonNegative());
+
+  unsigned Bits = 4;
+  EnumerateConstantRanges(Bits, [](const ConstantRange &CR) {
+    bool AllNegative = true;
+    bool AllNonNegative = true;
+    ForeachNumInConstantRange(CR, [&](const APInt &N) {
+      if (!N.isNegative())
+        AllNegative = false;
+      if (!N.isNonNegative())
+        AllNonNegative = false;
+    });
+    assert((CR.isEmptySet() || !AllNegative || !AllNonNegative) &&
+           "Only empty set can be both all negative and all non-negative");
+
+    EXPECT_EQ(AllNegative, CR.isAllNegative());
+    EXPECT_EQ(AllNonNegative, CR.isAllNonNegative());
+  });
+}
+
+TEST_F(ConstantRangeTest, UAddSat) {
+  TestUnsignedBinOpExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.uadd_sat(CR2);
+      },
+      [](const APInt &N1, const APInt &N2) {
+        return N1.uadd_sat(N2);
+      });
+}
+
+TEST_F(ConstantRangeTest, USubSat) {
+  TestUnsignedBinOpExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.usub_sat(CR2);
+      },
+      [](const APInt &N1, const APInt &N2) {
+        return N1.usub_sat(N2);
+      });
+}
+
+TEST_F(ConstantRangeTest, SAddSat) {
+  TestSignedBinOpExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.sadd_sat(CR2);
+      },
+      [](const APInt &N1, const APInt &N2) {
+        return N1.sadd_sat(N2);
+      });
+}
+
+TEST_F(ConstantRangeTest, SSubSat) {
+  TestSignedBinOpExhaustive(
+      [](const ConstantRange &CR1, const ConstantRange &CR2) {
+        return CR1.ssub_sat(CR2);
+      },
+      [](const APInt &N1, const APInt &N2) {
+        return N1.ssub_sat(N2);
+      });
+}
+
+TEST_F(ConstantRangeTest, Abs) {
+  unsigned Bits = 4;
+  EnumerateConstantRanges(Bits, [&](const ConstantRange &CR) {
+    // We're working with unsigned integers here, because it makes the signed
+    // min case non-wrapping.
+    APInt Min = APInt::getMaxValue(Bits);
+    APInt Max = APInt::getMinValue(Bits);
+    ForeachNumInConstantRange(CR, [&](const APInt &N) {
+      APInt AbsN = N.abs();
+      if (AbsN.ult(Min))
+        Min = AbsN;
+      if (AbsN.ugt(Max))
+        Max = AbsN;
+    });
+
+    ConstantRange AbsCR = CR.abs();
+    if (Min.ugt(Max)) {
+      EXPECT_TRUE(AbsCR.isEmptySet());
+      return;
+    }
+
+    ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1);
+    EXPECT_EQ(Exact, AbsCR);
+  });
+}
+
 }  // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp b/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp
index cf67e55..6c3497a 100644
--- a/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ConstantsTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/ConstantsTest.cpp - Constants unit tests ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -230,7 +229,7 @@
   #define P6STR "bitcast (i32 ptrtoint (i32** @dummy2 to i32) to <2 x i16>)"
 
   CHECK(ConstantExpr::getNeg(P0), "sub i32 0, " P0STR);
-  CHECK(ConstantExpr::getFNeg(P1), "fsub float -0.000000e+00, " P1STR);
+  CHECK(ConstantExpr::getFNeg(P1), "fneg float " P1STR);
   CHECK(ConstantExpr::getNot(P0), "xor i32 " P0STR ", -1");
   CHECK(ConstantExpr::getAdd(P0, P0), "add i32 " P0STR ", " P0STR);
   CHECK(ConstantExpr::getAdd(P0, P0, false, true), "add nsw i32 " P0STR ", "
@@ -476,5 +475,113 @@
   ASSERT_EQ(cast<ConstantExpr>(C)->getOpcode(), Instruction::BitCast);
 }
 
+bool foldFuncPtrAndConstToNull(LLVMContext &Context, Module *TheModule,
+                               uint64_t AndValue, unsigned FunctionAlign = 0) {
+  Type *VoidType(Type::getVoidTy(Context));
+  FunctionType *FuncType(FunctionType::get(VoidType, false));
+  Function *Func(Function::Create(
+      FuncType, GlobalValue::ExternalLinkage, "", TheModule));
+
+  if (FunctionAlign) Func->setAlignment(FunctionAlign);
+
+  IntegerType *ConstantIntType(Type::getInt32Ty(Context));
+  ConstantInt *TheConstant(ConstantInt::get(ConstantIntType, AndValue));
+
+  Constant *TheConstantExpr(
+      ConstantExpr::getPtrToInt(Func, ConstantIntType));
+
+
+  bool result = ConstantExpr::get(Instruction::And, TheConstantExpr,
+                           TheConstant)->isNullValue();
+
+  if (!TheModule) {
+    // If the Module exists then it will delete the Function.
+    delete Func;
+  }
+
+  return result;
+}
+
+TEST(ConstantsTest, FoldFunctionPtrAlignUnknownAnd2) {
+  LLVMContext Context;
+  Module TheModule("TestModule", Context);
+  // When the DataLayout doesn't specify a function pointer alignment we
+  // assume in this case that it is 4 byte aligned. This is a bug but we can't
+  // fix it directly because it causes a code size regression on X86.
+  // FIXME: This test should be changed once existing targets have
+  // appropriate defaults. See associated FIXME in ConstantFoldBinaryInstruction
+  ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2));
+}
+
+TEST(ConstantsTest, DontFoldFunctionPtrAlignUnknownAnd4) {
+  LLVMContext Context;
+  Module TheModule("TestModule", Context);
+  ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 4));
+}
+
+TEST(ConstantsTest, FoldFunctionPtrAlign4) {
+  LLVMContext Context;
+  Module TheModule("TestModule", Context);
+  const char* AlignmentStrings[] = { "Fi32", "Fn32" };
+
+  for (unsigned AndValue = 1; AndValue <= 2; ++AndValue) {
+    for (const char *AlignmentString : AlignmentStrings) {
+      TheModule.setDataLayout(AlignmentString);
+      ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, AndValue));
+    }
+  }
+}
+
+TEST(ConstantsTest, DontFoldFunctionPtrAlign1) {
+  LLVMContext Context;
+  Module TheModule("TestModule", Context);
+  const char* AlignmentStrings[] = { "Fi8", "Fn8" };
+
+  for (const char* AlignmentString : AlignmentStrings) {
+    TheModule.setDataLayout(AlignmentString);
+    ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2));
+  }
+}
+
+TEST(ConstantsTest, FoldFunctionAlign4PtrAlignMultiple) {
+  LLVMContext Context;
+  Module TheModule("TestModule", Context);
+  TheModule.setDataLayout("Fn8");
+  ASSERT_TRUE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, 4));
+}
+
+TEST(ConstantsTest, DontFoldFunctionAlign4PtrAlignIndependent) {
+  LLVMContext Context;
+  Module TheModule("TestModule", Context);
+  TheModule.setDataLayout("Fi8");
+  ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, &TheModule, 2, 4));
+}
+
+TEST(ConstantsTest, DontFoldFunctionPtrIfNoModule) {
+  LLVMContext Context;
+  // Even though the function is explicitly 4 byte aligned, in the absence of a
+  // DataLayout we can't assume that the function pointer is aligned.
+  ASSERT_FALSE(foldFuncPtrAndConstToNull(Context, nullptr, 2, 4));
+}
+
+TEST(ConstantsTest, FoldGlobalVariablePtr) {
+  LLVMContext Context;
+
+  IntegerType *IntType(Type::getInt32Ty(Context));
+
+  std::unique_ptr<GlobalVariable> Global(
+      new GlobalVariable(IntType, true, GlobalValue::ExternalLinkage));
+
+  Global->setAlignment(4);
+
+  ConstantInt *TheConstant(ConstantInt::get(IntType, 2));
+
+  Constant *TheConstantExpr(
+      ConstantExpr::getPtrToInt(Global.get(), IntType));
+
+  ASSERT_TRUE(ConstantExpr::get( \
+      Instruction::And, TheConstantExpr, TheConstant)->isNullValue());
+}
+
 }  // end anonymous namespace
 }  // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/IR/DataLayoutTest.cpp b/src/llvm-project/llvm/unittests/IR/DataLayoutTest.cpp
new file mode 100644
index 0000000..e7ed70b
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/IR/DataLayoutTest.cpp
@@ -0,0 +1,47 @@
+//===- ConstantRangeTest.cpp - ConstantRange tests ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/DataLayout.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(DataLayoutTest, FunctionPtrAlign) {
+  EXPECT_EQ(0U, DataLayout("").getFunctionPtrAlign());
+  EXPECT_EQ(1U, DataLayout("Fi8").getFunctionPtrAlign());
+  EXPECT_EQ(2U, DataLayout("Fi16").getFunctionPtrAlign());
+  EXPECT_EQ(4U, DataLayout("Fi32").getFunctionPtrAlign());
+  EXPECT_EQ(8U, DataLayout("Fi64").getFunctionPtrAlign());
+  EXPECT_EQ(1U, DataLayout("Fn8").getFunctionPtrAlign());
+  EXPECT_EQ(2U, DataLayout("Fn16").getFunctionPtrAlign());
+  EXPECT_EQ(4U, DataLayout("Fn32").getFunctionPtrAlign());
+  EXPECT_EQ(8U, DataLayout("Fn64").getFunctionPtrAlign());
+  EXPECT_EQ(DataLayout::FunctionPtrAlignType::Independent, \
+      DataLayout("").getFunctionPtrAlignType());
+  EXPECT_EQ(DataLayout::FunctionPtrAlignType::Independent, \
+      DataLayout("Fi8").getFunctionPtrAlignType());
+  EXPECT_EQ(DataLayout::FunctionPtrAlignType::MultipleOfFunctionAlign, \
+      DataLayout("Fn8").getFunctionPtrAlignType());
+  EXPECT_EQ(DataLayout("Fi8"), DataLayout("Fi8"));
+  EXPECT_NE(DataLayout("Fi8"), DataLayout("Fi16"));
+  EXPECT_NE(DataLayout("Fi8"), DataLayout("Fn8"));
+
+  DataLayout a(""), b("Fi8"), c("Fn8");
+  EXPECT_NE(a, b);
+  EXPECT_NE(a, c);
+  EXPECT_NE(b, c);
+
+  a = b;
+  EXPECT_EQ(a, b);
+  a = c;
+  EXPECT_EQ(a, c);
+}
+
+}  // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp b/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp
index a80df3c..9324790 100644
--- a/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DebugInfoTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo tests -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp b/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
index af77091..8031bf7 100644
--- a/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
@@ -1,9 +1,8 @@
 //===- DebugTypeODRUniquingTest.cpp - Debug type ODR uniquing tests -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp b/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp
index 6775fc1..a2d5805 100644
--- a/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp ----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp b/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp
index 7539bbc..7773856 100644
--- a/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/DominatorTreeTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/IR/DominatorTreeTest.cpp - Constants unit tests -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp b/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp
index 6838d7e..6f3e8f9 100644
--- a/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/FunctionTest.cpp
@@ -1,9 +1,8 @@
 //===- FunctionTest.cpp - Function unit tests -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -130,4 +129,29 @@
   EXPECT_TRUE(F->hasSection());
 }
 
+TEST(FunctionTest, GetPointerAlignment) {
+  LLVMContext Context;
+  Type *VoidType(Type::getVoidTy(Context));
+  FunctionType *FuncType(FunctionType::get(VoidType, false));
+  std::unique_ptr<Function> Func(Function::Create(
+      FuncType, GlobalValue::ExternalLinkage));
+  EXPECT_EQ(0U, Func->getPointerAlignment(DataLayout("")));
+  EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fi8")));
+  EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fn8")));
+  EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fi16")));
+  EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fn16")));
+  EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fi32")));
+  EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn32")));
+
+  Func->setAlignment(4U);
+
+  EXPECT_EQ(0U, Func->getPointerAlignment(DataLayout("")));
+  EXPECT_EQ(1U, Func->getPointerAlignment(DataLayout("Fi8")));
+  EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn8")));
+  EXPECT_EQ(2U, Func->getPointerAlignment(DataLayout("Fi16")));
+  EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn16")));
+  EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fi32")));
+  EXPECT_EQ(4U, Func->getPointerAlignment(DataLayout("Fn32")));
+}
+
 } // end namespace
diff --git a/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp b/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp
index db174fa..667b9ef 100644
--- a/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/IRBuilderTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -55,7 +54,7 @@
   CallInst *Call;
   IntrinsicInst *II;
 
-  V = Builder.CreateLoad(GV);
+  V = Builder.CreateLoad(GV->getValueType(), GV);
   I = cast<Instruction>(Builder.CreateFAdd(V, V));
   I->setHasNoInfs(true);
   I->setHasNoNaNs(false);
@@ -123,6 +122,70 @@
   EXPECT_FALSE(II->hasNoNaNs());
 }
 
+TEST_F(IRBuilderTest, ConstrainedFP) {
+  IRBuilder<> Builder(BB);
+  Value *V;
+  CallInst *Call;
+  IntrinsicInst *II;
+
+  V = Builder.CreateLoad(GV->getValueType(), GV);
+
+  // See if we get constrained intrinsics instead of non-constrained
+  // instructions.
+  Builder.setIsFPConstrained(true);
+
+  V = Builder.CreateFAdd(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);
+
+  V = Builder.CreateFSub(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fsub);
+
+  V = Builder.CreateFMul(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fmul);
+  
+  V = Builder.CreateFDiv(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fdiv);
+  
+  V = Builder.CreateFRem(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem);
+
+  // Verify the codepaths for setting and overriding the default metadata.
+  V = Builder.CreateFAdd(V, V);
+  ASSERT_TRUE(isa<ConstrainedFPIntrinsic>(V));
+  auto *CII = cast<ConstrainedFPIntrinsic>(V);
+  ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebStrict);
+  ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmDynamic);
+
+  Builder.setDefaultConstrainedExcept(ConstrainedFPIntrinsic::ebIgnore);
+  Builder.setDefaultConstrainedRounding(ConstrainedFPIntrinsic::rmUpward);
+  V = Builder.CreateFAdd(V, V);
+  CII = cast<ConstrainedFPIntrinsic>(V);
+  ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebIgnore);
+  ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmUpward);
+
+  // Now override the defaults.
+  Call = Builder.CreateConstrainedFPBinOp(
+        Intrinsic::experimental_constrained_fadd, V, V, nullptr, "", nullptr,
+        ConstrainedFPIntrinsic::rmDownward, ConstrainedFPIntrinsic::ebMayTrap);
+  CII = cast<ConstrainedFPIntrinsic>(Call);
+  EXPECT_EQ(CII->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);
+  ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebMayTrap);
+  ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmDownward);
+
+  Builder.CreateRetVoid();
+  EXPECT_FALSE(verifyModule(*M));
+}
+
 TEST_F(IRBuilderTest, Lifetime) {
   IRBuilder<> Builder(BB);
   AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
@@ -203,12 +266,34 @@
   delete DL;
 }
 
+TEST_F(IRBuilderTest, UnaryOperators) {
+  IRBuilder<NoFolder> Builder(BB);
+  Value *V = Builder.CreateLoad(GV->getValueType(), GV);
+
+  // Test CreateUnOp(X)
+  Value *U = Builder.CreateUnOp(Instruction::FNeg, V);
+  ASSERT_TRUE(isa<Instruction>(U));
+  ASSERT_TRUE(isa<FPMathOperator>(U));
+  ASSERT_TRUE(isa<UnaryOperator>(U));
+  ASSERT_FALSE(isa<BinaryOperator>(U));
+
+  // Test CreateFNegFMF(X)
+  Instruction *I = cast<Instruction>(V);
+  I->setHasNoSignedZeros(true);
+  I->setHasNoNaNs(true);
+  Value *VFMF = Builder.CreateFNegFMF(V, I);
+  Instruction *IFMF = cast<Instruction>(VFMF);
+  EXPECT_TRUE(IFMF->hasNoSignedZeros());
+  EXPECT_TRUE(IFMF->hasNoNaNs());
+  EXPECT_FALSE(IFMF->hasAllowReassoc());
+}
+
 TEST_F(IRBuilderTest, FastMathFlags) {
   IRBuilder<> Builder(BB);
   Value *F, *FC;
   Instruction *FDiv, *FAdd, *FCmp, *FCall;
 
-  F = Builder.CreateLoad(GV);
+  F = Builder.CreateLoad(GV->getValueType(), GV);
   F = Builder.CreateFAdd(F, F);
 
   EXPECT_FALSE(Builder.getFastMathFlags().any());
@@ -354,7 +439,7 @@
   FCall = Builder.CreateCall(Callee, None);
   EXPECT_FALSE(FCall->hasNoNaNs());
 
-  Value *V = 
+  Function *V =
       Function::Create(CalleeTy, Function::ExternalLinkage, "", M.get());
   FCall = Builder.CreateCall(V, None);
   EXPECT_FALSE(FCall->hasNoNaNs());
@@ -375,7 +460,7 @@
 
   Builder.clearFastMathFlags();
 
-  // To test a copy, make sure that a '0' and a '1' change state. 
+  // To test a copy, make sure that a '0' and a '1' change state.
   F = Builder.CreateFDiv(F, F);
   ASSERT_TRUE(isa<Instruction>(F));
   FDiv = cast<Instruction>(F);
@@ -395,7 +480,7 @@
   // Test instructions.
   GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,
                                          GlobalValue::ExternalLinkage, nullptr);
-  Value *V = Builder.CreateLoad(G);
+  Value *V = Builder.CreateLoad(G->getValueType(), G);
   EXPECT_TRUE(
       cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());
   EXPECT_TRUE(
@@ -462,7 +547,7 @@
   EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
   EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());
 
-  Value *F = Builder.CreateLoad(GV);
+  Value *F = Builder.CreateLoad(GV->getValueType(), GV);
 
   {
     IRBuilder<>::InsertPointGuard Guard(Builder);
diff --git a/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp b/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp
index 080e35c..b2ea384 100644
--- a/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/InstructionsTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/InstructionsTest.cpp - Instructions unit tests ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -505,14 +504,15 @@
   LLVMContext C;
   Type *Int32Ty = Type::getInt32Ty(C);
   Type *ArgTys[] = {Int32Ty, Int32Ty, Int32Ty};
-  Type *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false);
+  FunctionType *FnTy = FunctionType::get(Int32Ty, ArgTys, /*isVarArg=*/false);
   Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
   Value *Args[] = {
     ConstantInt::get(Int32Ty, 1),
     ConstantInt::get(Int32Ty, 2),
     ConstantInt::get(Int32Ty, 3)
   };
-  std::unique_ptr<CallInst> Call(CallInst::Create(Callee, Args, "result"));
+  std::unique_ptr<CallInst> Call(
+      CallInst::Create(FnTy, Callee, Args, "result"));
 
   // Test cloning the tail call kind.
   CallInst::TailCallKind Kinds[] = {CallInst::TCK_None, CallInst::TCK_Tail,
@@ -538,12 +538,12 @@
 TEST(InstructionsTest, AlterCallBundles) {
   LLVMContext C;
   Type *Int32Ty = Type::getInt32Ty(C);
-  Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
+  FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
   Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
   Value *Args[] = {ConstantInt::get(Int32Ty, 42)};
   OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty));
   std::unique_ptr<CallInst> Call(
-      CallInst::Create(Callee, Args, OldBundle, "result"));
+      CallInst::Create(FnTy, Callee, Args, OldBundle, "result"));
   Call->setTailCallKind(CallInst::TailCallKind::TCK_NoTail);
   AttrBuilder AB;
   AB.addAttribute(Attribute::Cold);
@@ -565,14 +565,15 @@
 TEST(InstructionsTest, AlterInvokeBundles) {
   LLVMContext C;
   Type *Int32Ty = Type::getInt32Ty(C);
-  Type *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
+  FunctionType *FnTy = FunctionType::get(Int32Ty, Int32Ty, /*isVarArg=*/false);
   Value *Callee = Constant::getNullValue(FnTy->getPointerTo());
   Value *Args[] = {ConstantInt::get(Int32Ty, 42)};
   std::unique_ptr<BasicBlock> NormalDest(BasicBlock::Create(C));
   std::unique_ptr<BasicBlock> UnwindDest(BasicBlock::Create(C));
   OperandBundleDef OldBundle("before", UndefValue::get(Int32Ty));
-  std::unique_ptr<InvokeInst> Invoke(InvokeInst::Create(
-      Callee, NormalDest.get(), UnwindDest.get(), Args, OldBundle, "result"));
+  std::unique_ptr<InvokeInst> Invoke(
+      InvokeInst::Create(FnTy, Callee, NormalDest.get(), UnwindDest.get(), Args,
+                         OldBundle, "result"));
   AttrBuilder AB;
   AB.addAttribute(Attribute::Cold);
   Invoke->setAttributes(
@@ -646,7 +647,8 @@
 
   {
     Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy());
-    auto *GI = cast<GetElementPtrInst>(B.CreateInBoundsGEP(GEPBase, {Arg0}));
+    auto *GI = cast<GetElementPtrInst>(
+        B.CreateInBoundsGEP(B.getInt8Ty(), GEPBase, Arg0));
     ASSERT_TRUE(GI->isInBounds());
     GI->dropPoisonGeneratingFlags();
     ASSERT_FALSE(GI->isInBounds());
@@ -751,6 +753,47 @@
   EXPECT_EQ(BB1.get(), Handle.getCaseSuccessor());
 }
 
+TEST(InstructionsTest, SwitchInstProfUpdateWrapper) {
+  LLVMContext C;
+
+  std::unique_ptr<BasicBlock> BB1, BB2, BB3;
+  BB1.reset(BasicBlock::Create(C));
+  BB2.reset(BasicBlock::Create(C));
+  BB3.reset(BasicBlock::Create(C));
+
+  // We create block 0 after the others so that it gets destroyed first and
+  // clears the uses of the other basic blocks.
+  std::unique_ptr<BasicBlock> BB0(BasicBlock::Create(C));
+
+  auto *Int32Ty = Type::getInt32Ty(C);
+
+  SwitchInst *SI =
+      SwitchInst::Create(UndefValue::get(Int32Ty), BB0.get(), 4, BB0.get());
+  SI->addCase(ConstantInt::get(Int32Ty, 1), BB1.get());
+  SI->addCase(ConstantInt::get(Int32Ty, 2), BB2.get());
+  SI->setMetadata(LLVMContext::MD_prof,
+                  MDBuilder(C).createBranchWeights({ 9, 1, 22 }));
+
+  {
+    SwitchInstProfUpdateWrapper SIW(*SI);
+    EXPECT_EQ(*SIW.getSuccessorWeight(0), 9u);
+    EXPECT_EQ(*SIW.getSuccessorWeight(1), 1u);
+    EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);
+    SIW.setSuccessorWeight(0, 99u);
+    SIW.setSuccessorWeight(1, 11u);
+    EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u);
+    EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u);
+    EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);
+  }
+
+  { // Create another wrapper and check that the data persist.
+    SwitchInstProfUpdateWrapper SIW(*SI);
+    EXPECT_EQ(*SIW.getSuccessorWeight(0), 99u);
+    EXPECT_EQ(*SIW.getSuccessorWeight(1), 11u);
+    EXPECT_EQ(*SIW.getSuccessorWeight(2), 22u);
+  }
+}
+
 TEST(InstructionsTest, CommuteShuffleMask) {
   SmallVector<int, 16> Indices({-1, 0, 7});
   ShuffleVectorInst::commuteShuffleMask(Indices, 4);
@@ -991,5 +1034,83 @@
   EXPECT_EQ(nullptr, Term->getNextNonDebugInstruction());
 }
 
+TEST(InstructionsTest, PhiIsNotFPMathOperator) {
+  LLVMContext Context;
+  IRBuilder<> Builder(Context);
+  MDBuilder MDHelper(Context);
+  Instruction *I = Builder.CreatePHI(Builder.getDoubleTy(), 0);
+  EXPECT_FALSE(isa<FPMathOperator>(I));
+  I->deleteValue();
+}
+
+TEST(InstructionsTest, FNegInstruction) {
+  LLVMContext Context;
+  Type *FltTy = Type::getFloatTy(Context);
+  Constant *One = ConstantFP::get(FltTy, 1.0);
+  BinaryOperator *FAdd = BinaryOperator::CreateFAdd(One, One);
+  FAdd->setHasNoNaNs(true);
+  UnaryOperator *FNeg = UnaryOperator::CreateFNegFMF(One, FAdd);
+  EXPECT_TRUE(FNeg->hasNoNaNs());
+  EXPECT_FALSE(FNeg->hasNoInfs());
+  EXPECT_FALSE(FNeg->hasNoSignedZeros());
+  EXPECT_FALSE(FNeg->hasAllowReciprocal());
+  EXPECT_FALSE(FNeg->hasAllowContract());
+  EXPECT_FALSE(FNeg->hasAllowReassoc());
+  EXPECT_FALSE(FNeg->hasApproxFunc());
+  FAdd->deleteValue();
+  FNeg->deleteValue();
+}
+
+TEST(InstructionsTest, CallBrInstruction) {
+  LLVMContext Context;
+  std::unique_ptr<Module> M = parseIR(Context, R"(
+define void @foo() {
+entry:
+  callbr void asm sideeffect "// XXX: ${0:l}", "X"(i8* blockaddress(@foo, %branch_test.exit))
+          to label %land.rhs.i [label %branch_test.exit]
+
+land.rhs.i:
+  br label %branch_test.exit
+
+branch_test.exit:
+  %0 = phi i1 [ true, %entry ], [ false, %land.rhs.i ]
+  br i1 %0, label %if.end, label %if.then
+
+if.then:
+  ret void
+
+if.end:
+  ret void
+}
+)");
+  Function *Foo = M->getFunction("foo");
+  auto BBs = Foo->getBasicBlockList().begin();
+  CallBrInst &CBI = cast<CallBrInst>(BBs->front());
+  ++BBs;
+  ++BBs;
+  BasicBlock &BranchTestExit = *BBs;
+  ++BBs;
+  BasicBlock &IfThen = *BBs;
+
+  // Test that setting the first indirect destination of callbr updates the dest
+  EXPECT_EQ(&BranchTestExit, CBI.getIndirectDest(0));
+  CBI.setIndirectDest(0, &IfThen);
+  EXPECT_EQ(&IfThen, CBI.getIndirectDest(0));
+
+  // Further, test that changing the indirect destination updates the arg
+  // operand to use the block address of the new indirect destination basic
+  // block. This is a critical invariant of CallBrInst.
+  BlockAddress *IndirectBA = BlockAddress::get(CBI.getIndirectDest(0));
+  BlockAddress *ArgBA = cast<BlockAddress>(CBI.getArgOperand(0));
+  EXPECT_EQ(IndirectBA, ArgBA)
+      << "After setting the indirect destination, callbr had an indirect "
+         "destination of '"
+      << CBI.getIndirectDest(0)->getName() << "', but a argument of '"
+      << ArgBA->getBasicBlock()->getName() << "'. These should always match:\n"
+      << CBI;
+  EXPECT_EQ(IndirectBA->getBasicBlock(), &IfThen);
+  EXPECT_EQ(ArgBA->getBasicBlock(), &IfThen);
+}
+
 } // end anonymous namespace
 } // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp b/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp
index 0d12126..a500346 100644
--- a/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/IntrinsicsTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/IntrinsicsTest.cpp - ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp b/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp
index 9f5f431..6c0c251 100644
--- a/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/LegacyPassManagerTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/LegacyPassManager.cpp - Legacy PassManager tests --===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -401,7 +400,12 @@
     struct CustomOptPassGate : public OptPassGate {
       bool Skip;
       CustomOptPassGate(bool Skip) : Skip(Skip) { }
-      bool shouldRunPass(const Pass *P, const Module &U) { return !Skip; }
+      bool shouldRunPass(const Pass *P, StringRef IRDescription) {
+        if (P->getPassKind() == PT_Module)
+          return !Skip;
+        return OptPassGate::shouldRunPass(P, IRDescription);
+      }
+      bool isEnabled() const { return true; }
     };
 
     // Optional module pass.
diff --git a/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp b/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp
index ab2d34e..f8d08b5 100644
--- a/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/MDBuilderTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/MDBuilderTest.cpp - MDBuilder unit tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp b/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp
index 04f1ca6..f0ef15e5 100644
--- a/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ManglerTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/ManglerTest.cpp - Mangler unit tests --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp b/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp
index 883a582..c1bce90 100644
--- a/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/MetadataTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/IR/MetadataTest.cpp - Metadata unit tests ----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -118,8 +117,9 @@
         32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, "");
   }
   Function *getFunction(StringRef Name) {
-    return cast<Function>(M.getOrInsertFunction(
-        Name, FunctionType::get(Type::getVoidTy(Context), None, false)));
+    return Function::Create(
+        FunctionType::get(Type::getVoidTy(Context), None, false),
+        Function::ExternalLinkage, Name, M);
   }
 };
 typedef MetadataTest MDStringTest;
@@ -1050,35 +1050,41 @@
   EXPECT_EQ(0U, L1->getBaseDiscriminator());
   EXPECT_EQ(1U, L1->getDuplicationFactor());
 
-  auto L2 = L1->setBaseDiscriminator(1).getValue();
+  EXPECT_EQ(L1, L1->cloneWithBaseDiscriminator(0).getValue());
+  EXPECT_EQ(L1, L1->cloneByMultiplyingDuplicationFactor(0).getValue());
+  EXPECT_EQ(L1, L1->cloneByMultiplyingDuplicationFactor(1).getValue());
+
+  auto L2 = L1->cloneWithBaseDiscriminator(1).getValue();
   EXPECT_EQ(0U, L1->getBaseDiscriminator());
   EXPECT_EQ(1U, L1->getDuplicationFactor());
 
   EXPECT_EQ(1U, L2->getBaseDiscriminator());
   EXPECT_EQ(1U, L2->getDuplicationFactor());
 
-  auto L3 = L2->cloneWithDuplicationFactor(2).getValue();
+  auto L3 = L2->cloneByMultiplyingDuplicationFactor(2).getValue();
   EXPECT_EQ(1U, L3->getBaseDiscriminator());
   EXPECT_EQ(2U, L3->getDuplicationFactor());
 
-  auto L4 = L3->cloneWithDuplicationFactor(4).getValue();
+  EXPECT_EQ(L2, L2->cloneByMultiplyingDuplicationFactor(1).getValue());
+
+  auto L4 = L3->cloneByMultiplyingDuplicationFactor(4).getValue();
   EXPECT_EQ(1U, L4->getBaseDiscriminator());
   EXPECT_EQ(8U, L4->getDuplicationFactor());
 
-  auto L5 = L4->setBaseDiscriminator(2).getValue();
+  auto L5 = L4->cloneWithBaseDiscriminator(2).getValue();
   EXPECT_EQ(2U, L5->getBaseDiscriminator());
-  EXPECT_EQ(1U, L5->getDuplicationFactor());
+  EXPECT_EQ(8U, L5->getDuplicationFactor());
 
   // Check extreme cases
-  auto L6 = L1->setBaseDiscriminator(0xfff).getValue();
+  auto L6 = L1->cloneWithBaseDiscriminator(0xfff).getValue();
   EXPECT_EQ(0xfffU, L6->getBaseDiscriminator());
-  EXPECT_EQ(
-      0xfffU,
-      L6->cloneWithDuplicationFactor(0xfff).getValue()->getDuplicationFactor());
+  EXPECT_EQ(0xfffU, L6->cloneByMultiplyingDuplicationFactor(0xfff)
+                        .getValue()
+                        ->getDuplicationFactor());
 
   // Check we return None for unencodable cases.
-  EXPECT_EQ(None, L4->setBaseDiscriminator(0x1000));
-  EXPECT_EQ(None, L4->cloneWithDuplicationFactor(0x1000));
+  EXPECT_EQ(None, L4->cloneWithBaseDiscriminator(0x1000));
+  EXPECT_EQ(None, L4->cloneByMultiplyingDuplicationFactor(0x1000));
 }
 
 
@@ -2329,7 +2335,11 @@
   // Test DIExpression::prepend().
   uint64_t Elts0[] = {dwarf::DW_OP_LLVM_fragment, 0, 32};
   auto *N0 = DIExpression::get(Context, Elts0);
-  auto *N0WithPrependedOps = DIExpression::prepend(N0, true, 64, true, true);
+  uint8_t DIExprFlags = DIExpression::ApplyOffset;
+  DIExprFlags |= DIExpression::DerefBefore;
+  DIExprFlags |= DIExpression::DerefAfter;
+  DIExprFlags |= DIExpression::StackValue;
+  auto *N0WithPrependedOps = DIExpression::prepend(N0, DIExprFlags, 64);
   uint64_t Elts1[] = {dwarf::DW_OP_deref,
                       dwarf::DW_OP_plus_uconst, 64,
                       dwarf::DW_OP_deref,
@@ -2746,7 +2756,7 @@
   F = getFunction("bar");
   EXPECT_FALSE(F->getEntryCount().hasValue());
   F->setEntryCount(123, Function::PCT_Synthetic);
-  Count = F->getEntryCount();
+  Count = F->getEntryCount(true /*allow synthetic*/);
   EXPECT_TRUE(Count.hasValue());
   EXPECT_EQ(123u, Count.getCount());
   EXPECT_EQ(Function::PCT_Synthetic, Count.getType());
diff --git a/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp b/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp
index af55a09..ae420bb 100644
--- a/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ModuleTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
index 63fdc67..bb7e227 100644
--- a/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/PassBuilderCallbacksTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/IR/PassBuilderCallbacksTest.cpp - PB Callback Tests --===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -415,7 +414,8 @@
                   "exit:\n"
                   "  ret void\n"
                   "}\n")),
-        CallbacksHandle(), PB(nullptr, None, &CallbacksHandle.Callbacks),
+        CallbacksHandle(),
+        PB(nullptr, PipelineTuningOptions(), None, &CallbacksHandle.Callbacks),
         PM(true), LAM(true), FAM(true), CGAM(true), AM(true) {
 
     /// Register a callback for analysis registration.
diff --git a/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp b/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp
index 13b87f1..304803d 100644
--- a/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/PassManagerTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp b/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp
index 976e42d..600494f 100644
--- a/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp
+++ b/src/llvm-project/llvm/unittests/IR/PatternMatch.cpp
@@ -1,9 +1,8 @@
 //===---- llvm/unittest/IR/PatternMatch.cpp - PatternMatch unit tests ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -65,6 +64,396 @@
   EXPECT_FALSE(m_OneUse(m_Value()).match(Leaf));
 }
 
+TEST_F(PatternMatchTest, SpecificIntEQ) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_EQ, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntNE) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_NE, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntUGT) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGT, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntUGE) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_UGE, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntULT) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULT, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntULE) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_ULE, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSGT) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGT, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSGE) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SGE, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSLT) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLT, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
+TEST_F(PatternMatchTest, SpecificIntSLE) {
+  Type *IntTy = IRB.getInt32Ty();
+  unsigned BitWidth = IntTy->getScalarSizeInBits();
+
+  Value *Zero = ConstantInt::get(IntTy, 0);
+  Value *One = ConstantInt::get(IntTy, 1);
+  Value *NegOne = ConstantInt::get(IntTy, -1);
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 0))
+          .match(NegOne));
+
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))
+          .match(Zero));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, 1))
+          .match(NegOne));
+
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))
+          .match(Zero));
+  EXPECT_FALSE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))
+          .match(One));
+  EXPECT_TRUE(
+      m_SpecificInt_ICMP(ICmpInst::Predicate::ICMP_SLE, APInt(BitWidth, -1))
+          .match(NegOne));
+}
+
 TEST_F(PatternMatchTest, CommutativeDeferredValue) {
   Value *X = IRB.getInt32(1);
   Value *Y = IRB.getInt32(2);
@@ -398,7 +787,7 @@
   //  store i32 42, i32* %0
 
   Value *Alloca = IRB.CreateAlloca(IRB.getInt32Ty());
-  Value *LoadInst = IRB.CreateLoad(Alloca);
+  Value *LoadInst = IRB.CreateLoad(IRB.getInt32Ty(), Alloca);
   Value *FourtyTwo = IRB.getInt32(42);
   Value *StoreInst = IRB.CreateStore(FourtyTwo, Alloca);
   Value *MatchLoad, *MatchStoreVal, *MatchStorePointer;
@@ -590,6 +979,35 @@
   EXPECT_TRUE(match(VectorZeroUndef, m_AnyZeroFP()));
 }
 
+TEST_F(PatternMatchTest, FloatingPointFNeg) {
+  Type *FltTy = IRB.getFloatTy();
+  Value *One = ConstantFP::get(FltTy, 1.0);
+  Value *Z = ConstantFP::get(FltTy, 0.0);
+  Value *NZ = ConstantFP::get(FltTy, -0.0);
+  Value *V = IRB.CreateFNeg(One);
+  Value *V1 = IRB.CreateFSub(NZ, One);
+  Value *V2 = IRB.CreateFSub(Z, One);
+  Value *V3 = IRB.CreateFAdd(NZ, One);
+  Value *Match;
+
+  // Test FNeg(1.0)
+  EXPECT_TRUE(match(V, m_FNeg(m_Value(Match))));
+  EXPECT_EQ(One, Match);
+
+  // Test FSub(-0.0, 1.0)
+  EXPECT_TRUE(match(V1, m_FNeg(m_Value(Match))));
+  EXPECT_EQ(One, Match);
+
+  // Test FSub(0.0, 1.0)
+  EXPECT_FALSE(match(V2, m_FNeg(m_Value(Match))));
+  cast<Instruction>(V2)->setHasNoSignedZeros(true);
+  EXPECT_TRUE(match(V2, m_FNeg(m_Value(Match))));
+  EXPECT_EQ(One, Match);
+
+  // Test FAdd(-0.0, 1.0)
+  EXPECT_FALSE(match(V3, m_FNeg(m_Value(Match))));
+}
+
 template <typename T> struct MutableConstTest : PatternMatchTest { };
 
 typedef ::testing::Types<std::tuple<Value*, Instruction*>,
diff --git a/src/llvm-project/llvm/unittests/IR/TimePassesTest.cpp b/src/llvm-project/llvm/unittests/IR/TimePassesTest.cpp
new file mode 100644
index 0000000..a766522
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/IR/TimePassesTest.cpp
@@ -0,0 +1,169 @@
+//===- unittests/IR/TimePassesTest.cpp - TimePassesHandler tests ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <gtest/gtest.h>
+#include <llvm/ADT/SmallString.h>
+#include "llvm/IR/LegacyPassManager.h"
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
+#include <llvm/IR/PassInstrumentation.h>
+#include <llvm/IR/PassManager.h>
+#include <llvm/IR/PassTimingInfo.h>
+#include <llvm/Support/raw_ostream.h>
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Define dummy passes for legacy pass manager run.
+
+namespace llvm {
+
+void initializePass1Pass(PassRegistry &);
+void initializePass2Pass(PassRegistry &);
+
+namespace {
+struct Pass1 : public ModulePass {
+  static char ID;
+
+public:
+  Pass1() : ModulePass(ID) {}
+  bool runOnModule(Module &M) override { return false; }
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+  StringRef getPassName() const override { return "Pass1"; }
+};
+char Pass1::ID;
+
+struct Pass2 : public ModulePass {
+  static char ID;
+
+public:
+  Pass2() : ModulePass(ID) {}
+  bool runOnModule(Module &M) override { return false; }
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+  StringRef getPassName() const override { return "Pass2"; }
+};
+char Pass2::ID;
+} // namespace
+} // namespace llvm
+
+INITIALIZE_PASS(Pass1, "Pass1", "Pass1", false, false)
+INITIALIZE_PASS(Pass2, "Pass2", "Pass2", false, false)
+
+namespace {
+
+TEST(TimePassesTest, LegacyCustomOut) {
+  PassInstrumentationCallbacks PIC;
+  PassInstrumentation PI(&PIC);
+
+  LLVMContext Context;
+  Module M("TestModule", Context);
+
+  SmallString<0> TimePassesStr;
+  raw_svector_ostream ReportStream(TimePassesStr);
+
+  // Setup pass manager
+  legacy::PassManager PM1;
+  PM1.add(new llvm::Pass1());
+  PM1.add(new llvm::Pass2());
+
+  // Enable time-passes and run passes.
+  TimePassesIsEnabled = true;
+  PM1.run(M);
+
+  // Generating report.
+  reportAndResetTimings(&ReportStream);
+
+  // There should be Pass1 and Pass2 in the report
+  EXPECT_FALSE(TimePassesStr.empty());
+  EXPECT_TRUE(TimePassesStr.str().contains("report"));
+  EXPECT_TRUE(TimePassesStr.str().contains("Pass1"));
+  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+
+  // Clear and generate report again.
+  TimePassesStr.clear();
+  reportAndResetTimings(&ReportStream);
+
+  // Since we did not run any passes since last print, report should be empty.
+  EXPECT_TRUE(TimePassesStr.empty());
+
+  // Now run just a single pass to populate timers again.
+  legacy::PassManager PM2;
+  PM2.add(new llvm::Pass2());
+  PM2.run(M);
+
+  // Generate report again.
+  reportAndResetTimings(&ReportStream);
+
+  // There should be Pass2 in this report and no Pass1.
+  EXPECT_FALSE(TimePassesStr.str().empty());
+  EXPECT_TRUE(TimePassesStr.str().contains("report"));
+  EXPECT_FALSE(TimePassesStr.str().contains("Pass1"));
+  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+}
+
+class MyPass1 : public PassInfoMixin<MyPass1> {};
+class MyPass2 : public PassInfoMixin<MyPass2> {};
+
+TEST(TimePassesTest, CustomOut) {
+  PassInstrumentationCallbacks PIC;
+  PassInstrumentation PI(&PIC);
+
+  LLVMContext Context;
+  Module M("TestModule", Context);
+  MyPass1 Pass1;
+  MyPass2 Pass2;
+
+  SmallString<0> TimePassesStr;
+  raw_svector_ostream ReportStream(TimePassesStr);
+
+  // Setup time-passes handler and redirect output to the stream.
+  std::unique_ptr<TimePassesHandler> TimePasses =
+      llvm::make_unique<TimePassesHandler>(true);
+  TimePasses->setOutStream(ReportStream);
+  TimePasses->registerCallbacks(PIC);
+
+  // Pretending that passes are running to trigger the timers.
+  PI.runBeforePass(Pass1, M);
+  PI.runBeforePass(Pass2, M);
+  PI.runAfterPass(Pass2, M);
+  PI.runAfterPass(Pass1, M);
+
+  // Generating report.
+  TimePasses->print();
+
+  // There should be Pass1 and Pass2 in the report
+  EXPECT_FALSE(TimePassesStr.empty());
+  EXPECT_TRUE(TimePassesStr.str().contains("report"));
+  EXPECT_TRUE(TimePassesStr.str().contains("Pass1"));
+  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+
+  // Clear and generate report again.
+  TimePassesStr.clear();
+  TimePasses->print();
+  // Since we did not run any passes since last print, report should be empty.
+  EXPECT_TRUE(TimePassesStr.empty());
+
+  // Now trigger just a single pass to populate timers again.
+  PI.runBeforePass(Pass2, M);
+  PI.runAfterPass(Pass2, M);
+
+  // Generate report by deleting the handler.
+  TimePasses.reset();
+
+  // There should be Pass2 in this report and no Pass1.
+  EXPECT_FALSE(TimePassesStr.str().empty());
+  EXPECT_TRUE(TimePassesStr.str().contains("report"));
+  EXPECT_FALSE(TimePassesStr.str().contains("Pass1"));
+  EXPECT_TRUE(TimePassesStr.str().contains("Pass2"));
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/TypesTest.cpp b/src/llvm-project/llvm/unittests/IR/TypesTest.cpp
index f006db51..a147367 100644
--- a/src/llvm-project/llvm/unittests/IR/TypesTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/TypesTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/TypesTest.cpp - Type unit tests -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/UseTest.cpp b/src/llvm-project/llvm/unittests/IR/UseTest.cpp
index 51ac2f4..a647ec7 100644
--- a/src/llvm-project/llvm/unittests/IR/UseTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/UseTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/UseTest.cpp - Use unit tests ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/UserTest.cpp b/src/llvm-project/llvm/unittests/IR/UserTest.cpp
index 794dfc1..e495735 100644
--- a/src/llvm-project/llvm/unittests/IR/UserTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/UserTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/UserTest.cpp - User unit tests --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp b/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp
index 9a4ce15..b799ff0 100644
--- a/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ValueHandleTest.cpp
@@ -1,9 +1,8 @@
 //===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp b/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp
index cbcd6f6..9dcb4fa 100644
--- a/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ValueMapTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/ValueTest.cpp b/src/llvm-project/llvm/unittests/IR/ValueTest.cpp
index 90466b2..03523a7 100644
--- a/src/llvm-project/llvm/unittests/IR/ValueTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/ValueTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/ValueTest.cpp - Value unit tests ------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/IR/VectorTypesTest.cpp b/src/llvm-project/llvm/unittests/IR/VectorTypesTest.cpp
new file mode 100644
index 0000000..f3caf6d
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/IR/VectorTypesTest.cpp
@@ -0,0 +1,164 @@
+//===--- llvm/unittest/IR/VectorTypesTest.cpp - vector types unit tests ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/ScalableSize.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+TEST(VectorTypesTest, FixedLength) {
+  LLVMContext Ctx;
+
+  Type *Int16Ty = Type::getInt16Ty(Ctx);
+  Type *Int32Ty = Type::getInt32Ty(Ctx);
+  Type *Int64Ty = Type::getInt64Ty(Ctx);
+  Type *Float64Ty = Type::getDoubleTy(Ctx);
+
+  VectorType *V8Int32Ty = VectorType::get(Int32Ty, 8);
+  ASSERT_FALSE(V8Int32Ty->isScalable());
+  EXPECT_EQ(V8Int32Ty->getNumElements(), 8U);
+  EXPECT_EQ(V8Int32Ty->getElementType()->getScalarSizeInBits(), 32U);
+
+  VectorType *V8Int16Ty = VectorType::get(Int16Ty, {8, false});
+  ASSERT_FALSE(V8Int16Ty->isScalable());
+  EXPECT_EQ(V8Int16Ty->getNumElements(), 8U);
+  EXPECT_EQ(V8Int16Ty->getElementType()->getScalarSizeInBits(), 16U);
+
+  ElementCount EltCnt(4, false);
+  VectorType *V4Int64Ty = VectorType::get(Int64Ty, EltCnt);
+  ASSERT_FALSE(V4Int64Ty->isScalable());
+  EXPECT_EQ(V4Int64Ty->getNumElements(), 4U);
+  EXPECT_EQ(V4Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *V2Int64Ty = VectorType::get(Int64Ty, EltCnt/2);
+  ASSERT_FALSE(V2Int64Ty->isScalable());
+  EXPECT_EQ(V2Int64Ty->getNumElements(), 2U);
+  EXPECT_EQ(V2Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *V8Int64Ty = VectorType::get(Int64Ty, EltCnt*2);
+  ASSERT_FALSE(V8Int64Ty->isScalable());
+  EXPECT_EQ(V8Int64Ty->getNumElements(), 8U);
+  EXPECT_EQ(V8Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *V4Float64Ty = VectorType::get(Float64Ty, EltCnt);
+  ASSERT_FALSE(V4Float64Ty->isScalable());
+  EXPECT_EQ(V4Float64Ty->getNumElements(), 4U);
+  EXPECT_EQ(V4Float64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *ExtTy = VectorType::getExtendedElementVectorType(V8Int16Ty);
+  EXPECT_EQ(ExtTy, V8Int32Ty);
+  ASSERT_FALSE(ExtTy->isScalable());
+  EXPECT_EQ(ExtTy->getNumElements(), 8U);
+  EXPECT_EQ(ExtTy->getElementType()->getScalarSizeInBits(), 32U);
+
+  VectorType *TruncTy = VectorType::getTruncatedElementVectorType(V8Int32Ty);
+  EXPECT_EQ(TruncTy, V8Int16Ty);
+  ASSERT_FALSE(TruncTy->isScalable());
+  EXPECT_EQ(TruncTy->getNumElements(), 8U);
+  EXPECT_EQ(TruncTy->getElementType()->getScalarSizeInBits(), 16U);
+
+  VectorType *HalvedTy = VectorType::getHalfElementsVectorType(V4Int64Ty);
+  EXPECT_EQ(HalvedTy, V2Int64Ty);
+  ASSERT_FALSE(HalvedTy->isScalable());
+  EXPECT_EQ(HalvedTy->getNumElements(), 2U);
+  EXPECT_EQ(HalvedTy->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *DoubledTy = VectorType::getDoubleElementsVectorType(V4Int64Ty);
+  EXPECT_EQ(DoubledTy, V8Int64Ty);
+  ASSERT_FALSE(DoubledTy->isScalable());
+  EXPECT_EQ(DoubledTy->getNumElements(), 8U);
+  EXPECT_EQ(DoubledTy->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *ConvTy = VectorType::getInteger(V4Float64Ty);
+  EXPECT_EQ(ConvTy, V4Int64Ty);
+  ASSERT_FALSE(ConvTy->isScalable());
+  EXPECT_EQ(ConvTy->getNumElements(), 4U);
+  EXPECT_EQ(ConvTy->getElementType()->getScalarSizeInBits(), 64U);
+
+  EltCnt = V8Int64Ty->getElementCount();
+  EXPECT_EQ(EltCnt.Min, 8U);
+  ASSERT_FALSE(EltCnt.Scalable);
+}
+
+TEST(VectorTypesTest, Scalable) {
+  LLVMContext Ctx;
+
+  Type *Int16Ty = Type::getInt16Ty(Ctx);
+  Type *Int32Ty = Type::getInt32Ty(Ctx);
+  Type *Int64Ty = Type::getInt64Ty(Ctx);
+  Type *Float64Ty = Type::getDoubleTy(Ctx);
+
+  VectorType *ScV8Int32Ty = VectorType::get(Int32Ty, 8, true);
+  ASSERT_TRUE(ScV8Int32Ty->isScalable());
+  EXPECT_EQ(ScV8Int32Ty->getNumElements(), 8U);
+  EXPECT_EQ(ScV8Int32Ty->getElementType()->getScalarSizeInBits(), 32U);
+
+  VectorType *ScV8Int16Ty = VectorType::get(Int16Ty, {8, true});
+  ASSERT_TRUE(ScV8Int16Ty->isScalable());
+  EXPECT_EQ(ScV8Int16Ty->getNumElements(), 8U);
+  EXPECT_EQ(ScV8Int16Ty->getElementType()->getScalarSizeInBits(), 16U);
+
+  ElementCount EltCnt(4, true);
+  VectorType *ScV4Int64Ty = VectorType::get(Int64Ty, EltCnt);
+  ASSERT_TRUE(ScV4Int64Ty->isScalable());
+  EXPECT_EQ(ScV4Int64Ty->getNumElements(), 4U);
+  EXPECT_EQ(ScV4Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *ScV2Int64Ty = VectorType::get(Int64Ty, EltCnt/2);
+  ASSERT_TRUE(ScV2Int64Ty->isScalable());
+  EXPECT_EQ(ScV2Int64Ty->getNumElements(), 2U);
+  EXPECT_EQ(ScV2Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *ScV8Int64Ty = VectorType::get(Int64Ty, EltCnt*2);
+  ASSERT_TRUE(ScV8Int64Ty->isScalable());
+  EXPECT_EQ(ScV8Int64Ty->getNumElements(), 8U);
+  EXPECT_EQ(ScV8Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *ScV4Float64Ty = VectorType::get(Float64Ty, EltCnt);
+  ASSERT_TRUE(ScV4Float64Ty->isScalable());
+  EXPECT_EQ(ScV4Float64Ty->getNumElements(), 4U);
+  EXPECT_EQ(ScV4Float64Ty->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *ExtTy = VectorType::getExtendedElementVectorType(ScV8Int16Ty);
+  EXPECT_EQ(ExtTy, ScV8Int32Ty);
+  ASSERT_TRUE(ExtTy->isScalable());
+  EXPECT_EQ(ExtTy->getNumElements(), 8U);
+  EXPECT_EQ(ExtTy->getElementType()->getScalarSizeInBits(), 32U);
+
+  VectorType *TruncTy = VectorType::getTruncatedElementVectorType(ScV8Int32Ty);
+  EXPECT_EQ(TruncTy, ScV8Int16Ty);
+  ASSERT_TRUE(TruncTy->isScalable());
+  EXPECT_EQ(TruncTy->getNumElements(), 8U);
+  EXPECT_EQ(TruncTy->getElementType()->getScalarSizeInBits(), 16U);
+
+  VectorType *HalvedTy = VectorType::getHalfElementsVectorType(ScV4Int64Ty);
+  EXPECT_EQ(HalvedTy, ScV2Int64Ty);
+  ASSERT_TRUE(HalvedTy->isScalable());
+  EXPECT_EQ(HalvedTy->getNumElements(), 2U);
+  EXPECT_EQ(HalvedTy->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *DoubledTy = VectorType::getDoubleElementsVectorType(ScV4Int64Ty);
+  EXPECT_EQ(DoubledTy, ScV8Int64Ty);
+  ASSERT_TRUE(DoubledTy->isScalable());
+  EXPECT_EQ(DoubledTy->getNumElements(), 8U);
+  EXPECT_EQ(DoubledTy->getElementType()->getScalarSizeInBits(), 64U);
+
+  VectorType *ConvTy = VectorType::getInteger(ScV4Float64Ty);
+  EXPECT_EQ(ConvTy, ScV4Int64Ty);
+  ASSERT_TRUE(ConvTy->isScalable());
+  EXPECT_EQ(ConvTy->getNumElements(), 4U);
+  EXPECT_EQ(ConvTy->getElementType()->getScalarSizeInBits(), 64U);
+
+  EltCnt = ScV8Int64Ty->getElementCount();
+  EXPECT_EQ(EltCnt.Min, 8U);
+  ASSERT_TRUE(EltCnt.Scalable);
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp b/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp
index 53e5d6f..a85f0a2 100644
--- a/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/VerifierTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests --*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,7 +26,7 @@
   LLVMContext C;
   Module M("M", C);
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
-  Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
   BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
   BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
   ReturnInst::Create(C, Exit);
@@ -50,7 +49,7 @@
   LLVMContext C;
   Module M("M", C);
   FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
-  Function *F = cast<Function>(M.getOrInsertFunction("foo", FTy));
+  Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
   AttributeList AS = F->getAttributes();
   F->setAttributes(
       AS.addAttribute(C, AttributeList::ReturnIndex, Attribute::UWTable));
@@ -68,9 +67,9 @@
   Module M2("M2", C);
   Module M3("M3", C);
   FunctionType *FTy = FunctionType::get(Type::getInt32Ty(C), /*isVarArg=*/false);
-  Function *F1 = cast<Function>(M1.getOrInsertFunction("foo1", FTy));
-  Function *F2 = cast<Function>(M2.getOrInsertFunction("foo2", FTy));
-  Function *F3 = cast<Function>(M3.getOrInsertFunction("foo3", FTy));
+  Function *F1 = Function::Create(FTy, Function::ExternalLinkage, "foo1", M1);
+  Function *F2 = Function::Create(FTy, Function::ExternalLinkage, "foo2", M2);
+  Function *F3 = Function::Create(FTy, Function::ExternalLinkage, "foo3", M3);
 
   BasicBlock *Entry1 = BasicBlock::Create(C, "entry", F1);
   BasicBlock *Entry3 = BasicBlock::Create(C, "entry", F3);
@@ -174,8 +173,8 @@
     new GlobalVariable(M, Type::getInt8Ty(C), false,
                        GlobalValue::ExternalLinkage, nullptr, "g");
 
-    auto *F = cast<Function>(M.getOrInsertFunction(
-        "f", FunctionType::get(Type::getVoidTy(C), false)));
+    auto *F = Function::Create(FunctionType::get(Type::getVoidTy(C), false),
+                               Function::ExternalLinkage, "f", M);
     IRBuilder<> Builder(BasicBlock::Create(C, "", F));
     Builder.CreateUnreachable();
     F->setSubprogram(DIB.createFunction(
diff --git a/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp b/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp
index 4d2671c..2f64fe0 100644
--- a/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp
+++ b/src/llvm-project/llvm/unittests/IR/WaymarkTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/IR/WaymarkTest.cpp - getUser() unit tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp b/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp
index 4d9081f..42e5c6c 100644
--- a/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp
+++ b/src/llvm-project/llvm/unittests/LineEditor/LineEditor.cpp
@@ -1,9 +1,8 @@
 //===-- LineEditor.cpp ----------------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp b/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp
index b8e2449..832e50c 100644
--- a/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp
+++ b/src/llvm-project/llvm/unittests/Linker/LinkModulesTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -84,7 +83,7 @@
   GEPIndices.push_back(&*F->arg_begin());
 
   Value *GEP = Builder.CreateGEP(AT, GV, GEPIndices, "switch.gep");
-  Value *Load = Builder.CreateLoad(GEP, "switch.load");
+  Value *Load = Builder.CreateLoad(AT->getElementType(), GEP, "switch.load");
 
   Builder.CreateRet(Load);
 
diff --git a/src/llvm-project/llvm/unittests/MC/Disassembler.cpp b/src/llvm-project/llvm/unittests/MC/Disassembler.cpp
index ca9581a..cdb3444 100644
--- a/src/llvm-project/llvm/unittests/MC/Disassembler.cpp
+++ b/src/llvm-project/llvm/unittests/MC/Disassembler.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Object/Disassembler.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp b/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp
index 1b1a4d6..af1250d 100644
--- a/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp
+++ b/src/llvm-project/llvm/unittests/MC/DwarfLineTables.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/MC/DwarfLineTables.cpp ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -58,9 +57,7 @@
   raw_svector_ostream EncodingOS(Buffer);
   MCDwarfLineAddr::Encode(getContext(), Params, LineDelta, AddrDelta,
                           EncodingOS);
-  ArrayRef<uint8_t> Encoding(reinterpret_cast<uint8_t *>(Buffer.data()),
-                             Buffer.size());
-  EXPECT_EQ(ExpectedEncoding, Encoding);
+  EXPECT_EQ(ExpectedEncoding, arrayRefFromStringRef(Buffer));
 }
 
 TEST(DwarfLineTables, TestDefaultParams) {
diff --git a/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp b/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp
index b547f93..81b7fa3 100644
--- a/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp
+++ b/src/llvm-project/llvm/unittests/MC/StringTableBuilderTest.cpp
@@ -1,9 +1,8 @@
 //===----------- StringTableBuilderTest.cpp -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp b/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp
index eb46b22..587b2ee 100644
--- a/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp
+++ b/src/llvm-project/llvm/unittests/MC/TargetRegistry.cpp
@@ -1,9 +1,8 @@
 //===- unittests/MC/TargetRegistry.cpp ------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Object/CMakeLists.txt b/src/llvm-project/llvm/unittests/Object/CMakeLists.txt
index e1376bf..e0be1ba 100644
--- a/src/llvm-project/llvm/unittests/Object/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Object/CMakeLists.txt
@@ -1,9 +1,12 @@
 set(LLVM_LINK_COMPONENTS
+  BinaryFormat
   Object
   )
 
 add_llvm_unittest(ObjectTests
+  MinidumpTest.cpp
   SymbolSizeTest.cpp
   SymbolicFileTest.cpp
   )
 
+target_link_libraries(ObjectTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/Object/MinidumpTest.cpp b/src/llvm-project/llvm/unittests/Object/MinidumpTest.cpp
new file mode 100644
index 0000000..ba9af5a
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Object/MinidumpTest.cpp
@@ -0,0 +1,513 @@
+//===- MinidumpTest.cpp - Tests for Minidump.cpp --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/Minidump.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace minidump;
+
+static Expected<std::unique_ptr<MinidumpFile>> create(ArrayRef<uint8_t> Data) {
+  return MinidumpFile::create(
+      MemoryBufferRef(toStringRef(Data), "Test buffer"));
+}
+
+TEST(MinidumpFile, BasicInterface) {
+  std::vector<uint8_t> Data{                        // Header
+                            'M', 'D', 'M', 'P',     // Signature
+                            0x93, 0xa7, 0, 0,       // Version
+                            1, 0, 0, 0,             // NumberOfStreams,
+                            0x20, 0, 0, 0,          // StreamDirectoryRVA
+                            0, 1, 2, 3, 4, 5, 6, 7, // Checksum, TimeDateStamp
+                            8, 9, 0, 1, 2, 3, 4, 5, // Flags
+                                                    // Stream Directory
+                            3, 0, 0x67, 0x47, 7, 0, 0, 0, // Type, DataSize,
+                            0x2c, 0, 0, 0,                // RVA
+                                                          // Stream
+                            'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  // A very simple minidump file which contains just a single stream.
+  auto ExpectedFile = create(Data);
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  const MinidumpFile &File = **ExpectedFile;
+  const Header &H = File.header();
+  EXPECT_EQ(Header::MagicSignature, H.Signature);
+  EXPECT_EQ(Header::MagicVersion, H.Version);
+  EXPECT_EQ(1u, H.NumberOfStreams);
+  EXPECT_EQ(0x20u, H.StreamDirectoryRVA);
+  EXPECT_EQ(0x03020100u, H.Checksum);
+  EXPECT_EQ(0x07060504u, H.TimeDateStamp);
+  EXPECT_EQ(uint64_t(0x0504030201000908), H.Flags);
+
+  ASSERT_EQ(1u, File.streams().size());
+  const Directory &Stream0 = File.streams()[0];
+  EXPECT_EQ(StreamType::LinuxCPUInfo, Stream0.Type);
+  EXPECT_EQ(7u, Stream0.Location.DataSize);
+  EXPECT_EQ(0x2cu, Stream0.Location.RVA);
+
+  EXPECT_EQ("CPUINFO", toStringRef(File.getRawStream(Stream0)));
+  EXPECT_EQ("CPUINFO",
+            toStringRef(*File.getRawStream(StreamType::LinuxCPUInfo)));
+
+  EXPECT_THAT_EXPECTED(File.getSystemInfo(), Failed<BinaryError>());
+}
+
+// Use the input from the previous test, but corrupt it in various ways
+TEST(MinidumpFile, create_ErrorCases) {
+  std::vector<uint8_t> FileTooShort{'M', 'D', 'M', 'P'};
+  EXPECT_THAT_EXPECTED(create(FileTooShort), Failed<BinaryError>());
+
+  std::vector<uint8_t> WrongSignature{
+      // Header
+      '!', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      3, 0, 0x67, 0x47, 7, 0, 0, 0,         // Type, DataSize,
+      0x2c, 0, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(WrongSignature), Failed<BinaryError>());
+
+  std::vector<uint8_t> WrongVersion{
+      // Header
+      'M', 'D', 'M', 'P', 0x39, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      3, 0, 0x67, 0x47, 7, 0, 0, 0,         // Type, DataSize,
+      0x2c, 0, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(WrongVersion), Failed<BinaryError>());
+
+  std::vector<uint8_t> DirectoryAfterEOF{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 1, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      3, 0, 0x67, 0x47, 7, 0, 0, 0,         // Type, DataSize,
+      0x2c, 0, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(DirectoryAfterEOF), Failed<BinaryError>());
+
+  std::vector<uint8_t> TruncatedDirectory{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 1, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      3, 0, 0x67, 0x47, 7, 0, 0, 0,         // Type, DataSize,
+      0x2c, 0, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(TruncatedDirectory), Failed<BinaryError>());
+
+  std::vector<uint8_t> Stream0AfterEOF{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      3, 0, 0x67, 0x47, 7, 0, 0, 0,         // Type, DataSize,
+      0x2c, 1, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(Stream0AfterEOF), Failed<BinaryError>());
+
+  std::vector<uint8_t> Stream0Truncated{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      3, 0, 0x67, 0x47, 8, 0, 0, 0,         // Type, DataSize,
+      0x2c, 0, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(Stream0Truncated), Failed<BinaryError>());
+
+  std::vector<uint8_t> DuplicateStream{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      2, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      3, 0, 0x67, 0x47, 7, 0, 0, 0,         // Type, DataSize,
+      0x40, 0, 0, 0,                        // RVA
+                                            // Stream
+      3, 0, 0x67, 0x47, 7, 0, 0, 0,         // Type, DataSize,
+      0x40, 0, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(DuplicateStream), Failed<BinaryError>());
+
+  std::vector<uint8_t> DenseMapInfoConflict{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      0xff, 0xff, 0xff, 0xff, 7, 0, 0, 0,   // Type, DataSize,
+      0x2c, 0, 0, 0,                        // RVA
+                                            // Stream
+      'C', 'P', 'U', 'I', 'N', 'F', 'O'};
+  EXPECT_THAT_EXPECTED(create(DenseMapInfoConflict), Failed<BinaryError>());
+}
+
+TEST(MinidumpFile, IngoresDummyStreams) {
+  std::vector<uint8_t> TwoDummyStreams{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      2, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      0, 0, 0, 0, 0, 0, 0, 0,               // Type, DataSize,
+      0x20, 0, 0, 0,                        // RVA
+      0, 0, 0, 0, 0, 0, 0, 0,               // Type, DataSize,
+      0x20, 0, 0, 0,                        // RVA
+  };
+  auto ExpectedFile = create(TwoDummyStreams);
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  const MinidumpFile &File = **ExpectedFile;
+  ASSERT_EQ(2u, File.streams().size());
+  EXPECT_EQ(StreamType::Unused, File.streams()[0].Type);
+  EXPECT_EQ(StreamType::Unused, File.streams()[1].Type);
+  EXPECT_EQ(None, File.getRawStream(StreamType::Unused));
+}
+
+TEST(MinidumpFile, getSystemInfo) {
+  std::vector<uint8_t> Data{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      7, 0, 0, 0, 56, 0, 0, 0,              // Type, DataSize,
+      0x2c, 0, 0, 0,                        // RVA
+                                            // SystemInfo
+      0, 0, 1, 2,                           // ProcessorArch, ProcessorLevel
+      3, 4, 5, 6, // ProcessorRevision, NumberOfProcessors, ProductType
+      7, 8, 9, 0, 1, 2, 3, 4, // MajorVersion, MinorVersion
+      5, 6, 7, 8, 2, 0, 0, 0, // BuildNumber, PlatformId
+      1, 2, 3, 4, 5, 6, 7, 8, // CSDVersionRVA, SuiteMask, Reserved
+      'L', 'L', 'V', 'M', 'L', 'L', 'V', 'M', 'L', 'L', 'V', 'M', // VendorID
+      1, 2, 3, 4, 5, 6, 7, 8, // VersionInfo, FeatureInfo
+      9, 0, 1, 2,             // AMDExtendedFeatures
+  };
+  auto ExpectedFile = create(Data);
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  const MinidumpFile &File = **ExpectedFile;
+
+  auto ExpectedInfo = File.getSystemInfo();
+  ASSERT_THAT_EXPECTED(ExpectedInfo, Succeeded());
+  const SystemInfo &Info = *ExpectedInfo;
+  EXPECT_EQ(ProcessorArchitecture::X86, Info.ProcessorArch);
+  EXPECT_EQ(0x0201, Info.ProcessorLevel);
+  EXPECT_EQ(0x0403, Info.ProcessorRevision);
+  EXPECT_EQ(5, Info.NumberOfProcessors);
+  EXPECT_EQ(6, Info.ProductType);
+  EXPECT_EQ(0x00090807u, Info.MajorVersion);
+  EXPECT_EQ(0x04030201u, Info.MinorVersion);
+  EXPECT_EQ(0x08070605u, Info.BuildNumber);
+  EXPECT_EQ(OSPlatform::Win32NT, Info.PlatformId);
+  EXPECT_EQ(0x04030201u, Info.CSDVersionRVA);
+  EXPECT_EQ(0x0605u, Info.SuiteMask);
+  EXPECT_EQ(0x0807u, Info.Reserved);
+  EXPECT_EQ("LLVMLLVMLLVM", llvm::StringRef(Info.CPU.X86.VendorID,
+                                            sizeof(Info.CPU.X86.VendorID)));
+  EXPECT_EQ(0x04030201u, Info.CPU.X86.VersionInfo);
+  EXPECT_EQ(0x08070605u, Info.CPU.X86.FeatureInfo);
+  EXPECT_EQ(0x02010009u, Info.CPU.X86.AMDExtendedFeatures);
+}
+
+TEST(MinidumpFile, getString) {
+  std::vector<uint8_t> ManyStrings{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      2, 0, 0, 0,                           // NumberOfStreams,
+      0x20, 0, 0, 0,                        // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      8, 9, 0, 1, 2, 3, 4, 5,               // Flags
+                                            // Stream Directory
+      0, 0, 0, 0, 0, 0, 0, 0,               // Type, DataSize,
+      0x20, 0, 0, 0,                        // RVA
+      1, 0, 0, 0, 0, 0,                     // String1 - odd length
+      0, 0, 1, 0, 0, 0,                     // String2 - too long
+      2, 0, 0, 0, 0, 0xd8,                  // String3 - invalid utf16
+      0, 0, 0, 0, 0, 0,                     // String4 - ""
+      2, 0, 0, 0, 'a', 0,                   // String5 - "a"
+      0,                                    // Mis-align next string
+      2, 0, 0, 0, 'a', 0,                   // String6 - "a"
+
+  };
+  auto ExpectedFile = create(ManyStrings);
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  const MinidumpFile &File = **ExpectedFile;
+  EXPECT_THAT_EXPECTED(File.getString(44), Failed<BinaryError>());
+  EXPECT_THAT_EXPECTED(File.getString(50), Failed<BinaryError>());
+  EXPECT_THAT_EXPECTED(File.getString(56), Failed<BinaryError>());
+  EXPECT_THAT_EXPECTED(File.getString(62), HasValue(""));
+  EXPECT_THAT_EXPECTED(File.getString(68), HasValue("a"));
+  EXPECT_THAT_EXPECTED(File.getString(75), HasValue("a"));
+
+  // Check the case when the size field does not fit into the remaining data.
+  EXPECT_THAT_EXPECTED(File.getString(ManyStrings.size() - 2),
+                       Failed<BinaryError>());
+}
+
+TEST(MinidumpFile, getModuleList) {
+  std::vector<uint8_t> OneModule{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      32, 0, 0, 0,                          // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      0, 0, 0, 0, 0, 0, 0, 0,               // Flags
+                                            // Stream Directory
+      4, 0, 0, 0, 112, 0, 0, 0,             // Type, DataSize,
+      44, 0, 0, 0,                          // RVA
+      // ModuleList
+      1, 0, 0, 0,             // NumberOfModules
+      1, 2, 3, 4, 5, 6, 7, 8, // BaseOfImage
+      9, 0, 1, 2, 3, 4, 5, 6, // SizeOfImage, Checksum
+      7, 8, 9, 0, 1, 2, 3, 4, // TimeDateStamp, ModuleNameRVA
+      0, 0, 0, 0, 0, 0, 0, 0, // Signature, StructVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // FileVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // ProductVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // FileFlagsMask, FileFlags
+      0, 0, 0, 0,             // FileOS
+      0, 0, 0, 0, 0, 0, 0, 0, // FileType, FileSubType
+      0, 0, 0, 0, 0, 0, 0, 0, // FileDate
+      1, 2, 3, 4, 5, 6, 7, 8, // CvRecord
+      9, 0, 1, 2, 3, 4, 5, 6, // MiscRecord
+      7, 8, 9, 0, 1, 2, 3, 4, // Reserved0
+      5, 6, 7, 8, 9, 0, 1, 2, // Reserved1
+  };
+  // Same as before, but with a padded module list.
+  std::vector<uint8_t> PaddedModule{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      32, 0, 0, 0,                          // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      0, 0, 0, 0, 0, 0, 0, 0,               // Flags
+                                            // Stream Directory
+      4, 0, 0, 0, 116, 0, 0, 0,             // Type, DataSize,
+      44, 0, 0, 0,                          // RVA
+      // ModuleList
+      1, 0, 0, 0,             // NumberOfModules
+      0, 0, 0, 0,             // Padding
+      1, 2, 3, 4, 5, 6, 7, 8, // BaseOfImage
+      9, 0, 1, 2, 3, 4, 5, 6, // SizeOfImage, Checksum
+      7, 8, 9, 0, 1, 2, 3, 4, // TimeDateStamp, ModuleNameRVA
+      0, 0, 0, 0, 0, 0, 0, 0, // Signature, StructVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // FileVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // ProductVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // FileFlagsMask, FileFlags
+      0, 0, 0, 0,             // FileOS
+      0, 0, 0, 0, 0, 0, 0, 0, // FileType, FileSubType
+      0, 0, 0, 0, 0, 0, 0, 0, // FileDate
+      1, 2, 3, 4, 5, 6, 7, 8, // CvRecord
+      9, 0, 1, 2, 3, 4, 5, 6, // MiscRecord
+      7, 8, 9, 0, 1, 2, 3, 4, // Reserved0
+      5, 6, 7, 8, 9, 0, 1, 2, // Reserved1
+  };
+
+  for (ArrayRef<uint8_t> Data : {OneModule, PaddedModule}) {
+    auto ExpectedFile = create(Data);
+    ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+    const MinidumpFile &File = **ExpectedFile;
+    Expected<ArrayRef<Module>> ExpectedModule = File.getModuleList();
+    ASSERT_THAT_EXPECTED(ExpectedModule, Succeeded());
+    ASSERT_EQ(1u, ExpectedModule->size());
+    const Module &M = ExpectedModule.get()[0];
+    EXPECT_EQ(0x0807060504030201u, M.BaseOfImage);
+    EXPECT_EQ(0x02010009u, M.SizeOfImage);
+    EXPECT_EQ(0x06050403u, M.Checksum);
+    EXPECT_EQ(0x00090807u, M.TimeDateStamp);
+    EXPECT_EQ(0x04030201u, M.ModuleNameRVA);
+    EXPECT_EQ(0x04030201u, M.CvRecord.DataSize);
+    EXPECT_EQ(0x08070605u, M.CvRecord.RVA);
+    EXPECT_EQ(0x02010009u, M.MiscRecord.DataSize);
+    EXPECT_EQ(0x06050403u, M.MiscRecord.RVA);
+    EXPECT_EQ(0x0403020100090807u, M.Reserved0);
+    EXPECT_EQ(0x0201000908070605u, M.Reserved1);
+  }
+
+  std::vector<uint8_t> StreamTooShort{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      32, 0, 0, 0,                          // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      0, 0, 0, 0, 0, 0, 0, 0,               // Flags
+                                            // Stream Directory
+      4, 0, 0, 0, 111, 0, 0, 0,             // Type, DataSize,
+      44, 0, 0, 0,                          // RVA
+      // ModuleList
+      1, 0, 0, 0,             // NumberOfModules
+      1, 2, 3, 4, 5, 6, 7, 8, // BaseOfImage
+      9, 0, 1, 2, 3, 4, 5, 6, // SizeOfImage, Checksum
+      7, 8, 9, 0, 1, 2, 3, 4, // TimeDateStamp, ModuleNameRVA
+      0, 0, 0, 0, 0, 0, 0, 0, // Signature, StructVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // FileVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // ProductVersion
+      0, 0, 0, 0, 0, 0, 0, 0, // FileFlagsMask, FileFlags
+      0, 0, 0, 0,             // FileOS
+      0, 0, 0, 0, 0, 0, 0, 0, // FileType, FileSubType
+      0, 0, 0, 0, 0, 0, 0, 0, // FileDate
+      1, 2, 3, 4, 5, 6, 7, 8, // CvRecord
+      9, 0, 1, 2, 3, 4, 5, 6, // MiscRecord
+      7, 8, 9, 0, 1, 2, 3, 4, // Reserved0
+      5, 6, 7, 8, 9, 0, 1, 2, // Reserved1
+  };
+  auto ExpectedFile = create(StreamTooShort);
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  const MinidumpFile &File = **ExpectedFile;
+  EXPECT_THAT_EXPECTED(File.getModuleList(), Failed<BinaryError>());
+}
+
+TEST(MinidumpFile, getThreadList) {
+  std::vector<uint8_t> OneThread{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      32, 0, 0, 0,                          // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      0, 0, 0, 0, 0, 0, 0, 0,               // Flags
+                                            // Stream Directory
+      3, 0, 0, 0, 52, 0, 0, 0,              // Type, DataSize,
+      44, 0, 0, 0,                          // RVA
+      // ThreadList
+      1, 0, 0, 0,             // NumberOfThreads
+      1, 2, 3, 4, 5, 6, 7, 8, // ThreadId, SuspendCount
+      9, 0, 1, 2, 3, 4, 5, 6, // PriorityClass, Priority
+      7, 8, 9, 0, 1, 2, 3, 4, // EnvironmentBlock
+      // Stack
+      5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+      3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+      // Context
+      1, 2, 3, 4, 5, 6, 7, 8, // DataSize, RVA
+  };
+  // Same as before, but with a padded thread list.
+  std::vector<uint8_t> PaddedThread{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      32, 0, 0, 0,                          // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      0, 0, 0, 0, 0, 0, 0, 0,               // Flags
+                                            // Stream Directory
+      3, 0, 0, 0, 56, 0, 0, 0,              // Type, DataSize,
+      44, 0, 0, 0,                          // RVA
+      // ThreadList
+      1, 0, 0, 0,             // NumberOfThreads
+      0, 0, 0, 0,             // Padding
+      1, 2, 3, 4, 5, 6, 7, 8, // ThreadId, SuspendCount
+      9, 0, 1, 2, 3, 4, 5, 6, // PriorityClass, Priority
+      7, 8, 9, 0, 1, 2, 3, 4, // EnvironmentBlock
+      // Stack
+      5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+      3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+      // Context
+      1, 2, 3, 4, 5, 6, 7, 8, // DataSize, RVA
+  };
+
+  for (ArrayRef<uint8_t> Data : {OneThread, PaddedThread}) {
+    auto ExpectedFile = create(Data);
+    ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+    const MinidumpFile &File = **ExpectedFile;
+    Expected<ArrayRef<Thread>> ExpectedThread = File.getThreadList();
+    ASSERT_THAT_EXPECTED(ExpectedThread, Succeeded());
+    ASSERT_EQ(1u, ExpectedThread->size());
+    const Thread &T = ExpectedThread.get()[0];
+    EXPECT_EQ(0x04030201u, T.ThreadId);
+    EXPECT_EQ(0x08070605u, T.SuspendCount);
+    EXPECT_EQ(0x02010009u, T.PriorityClass);
+    EXPECT_EQ(0x06050403u, T.Priority);
+    EXPECT_EQ(0x0403020100090807u, T.EnvironmentBlock);
+    EXPECT_EQ(0x0201000908070605u, T.Stack.StartOfMemoryRange);
+    EXPECT_EQ(0x06050403u, T.Stack.Memory.DataSize);
+    EXPECT_EQ(0x00090807u, T.Stack.Memory.RVA);
+    EXPECT_EQ(0x04030201u, T.Context.DataSize);
+    EXPECT_EQ(0x08070605u, T.Context.RVA);
+  }
+}
+
+TEST(MinidumpFile, getMemoryList) {
+  std::vector<uint8_t> OneRange{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      32, 0, 0, 0,                          // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      0, 0, 0, 0, 0, 0, 0, 0,               // Flags
+                                            // Stream Directory
+      5, 0, 0, 0, 20, 0, 0, 0,              // Type, DataSize,
+      44, 0, 0, 0,                          // RVA
+      // MemoryDescriptor
+      1, 0, 0, 0,             // NumberOfMemoryRanges
+      5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+      3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+  };
+  // Same as before, but with a padded memory list.
+  std::vector<uint8_t> PaddedRange{
+      // Header
+      'M', 'D', 'M', 'P', 0x93, 0xa7, 0, 0, // Signature, Version
+      1, 0, 0, 0,                           // NumberOfStreams,
+      32, 0, 0, 0,                          // StreamDirectoryRVA
+      0, 1, 2, 3, 4, 5, 6, 7,               // Checksum, TimeDateStamp
+      0, 0, 0, 0, 0, 0, 0, 0,               // Flags
+                                            // Stream Directory
+      5, 0, 0, 0, 24, 0, 0, 0,              // Type, DataSize,
+      44, 0, 0, 0,                          // RVA
+      // MemoryDescriptor
+      1, 0, 0, 0,             // NumberOfMemoryRanges
+      0, 0, 0, 0,             // Padding
+      5, 6, 7, 8, 9, 0, 1, 2, // StartOfMemoryRange
+      3, 4, 5, 6, 7, 8, 9, 0, // DataSize, RVA
+  };
+
+  for (ArrayRef<uint8_t> Data : {OneRange, PaddedRange}) {
+    auto ExpectedFile = create(Data);
+    ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+    const MinidumpFile &File = **ExpectedFile;
+    Expected<ArrayRef<MemoryDescriptor>> ExpectedRanges = File.getMemoryList();
+    ASSERT_THAT_EXPECTED(ExpectedRanges, Succeeded());
+    ASSERT_EQ(1u, ExpectedRanges->size());
+    const MemoryDescriptor &MD = ExpectedRanges.get()[0];
+    EXPECT_EQ(0x0201000908070605u, MD.StartOfMemoryRange);
+    EXPECT_EQ(0x06050403u, MD.Memory.DataSize);
+    EXPECT_EQ(0x00090807u, MD.Memory.RVA);
+  }
+}
diff --git a/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp b/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp
index ad9c40b..41269a6 100644
--- a/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Object/SymbolSizeTest.cpp
@@ -1,9 +1,8 @@
 //===- SymbolSizeTest.cpp - Tests for SymbolSize.cpp ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp b/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp
index ec954e5..3fc5d54 100644
--- a/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp
+++ b/src/llvm-project/llvm/unittests/Object/SymbolicFileTest.cpp
@@ -1,9 +1,8 @@
 //===- SymbolicFileTest.cpp - Tests for SymbolicFile.cpp ------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt b/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt
index baed10b..7fcc974 100644
--- a/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/ObjectYAML/CMakeLists.txt
@@ -1,8 +1,11 @@
 set(LLVM_LINK_COMPONENTS
+  Object
   ObjectYAML
   )
 
 add_llvm_unittest(ObjectYAMLTests
+  MinidumpYAMLTest.cpp
   YAMLTest.cpp
   )
 
+target_link_libraries(ObjectYAMLTests PRIVATE LLVMTestingSupport)
diff --git a/src/llvm-project/llvm/unittests/ObjectYAML/MinidumpYAMLTest.cpp b/src/llvm-project/llvm/unittests/ObjectYAML/MinidumpYAMLTest.cpp
new file mode 100644
index 0000000..66d44e0
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/ObjectYAML/MinidumpYAMLTest.cpp
@@ -0,0 +1,139 @@
+//===- MinidumpYAMLTest.cpp - Tests for Minidump<->YAML code --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ObjectYAML/MinidumpYAML.h"
+#include "llvm/Object/Minidump.h"
+#include "llvm/ObjectYAML/ObjectYAML.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::minidump;
+
+static Expected<std::unique_ptr<object::MinidumpFile>>
+toBinary(SmallVectorImpl<char> &Storage, StringRef Yaml) {
+  Storage.clear();
+  raw_svector_ostream OS(Storage);
+  if (Error E = MinidumpYAML::writeAsBinary(Yaml, OS))
+    return std::move(E);
+
+  return object::MinidumpFile::create(MemoryBufferRef(OS.str(), "Binary"));
+}
+
+TEST(MinidumpYAML, Basic) {
+  SmallString<0> Storage;
+  auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+  - Type:            SystemInfo
+    Processor Arch:  ARM64
+    Platform ID:     Linux
+    CPU:
+      CPUID:           0x05060708
+  - Type:            LinuxMaps
+    Text:             |
+      400d9000-400db000 r-xp 00000000 b3:04 227        /system/bin/app_process
+      400db000-400dc000 r--p 00001000 b3:04 227        /system/bin/app_process
+
+  - Type:            LinuxAuxv
+    Content:         DEADBEEFBAADF00D)");
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  object::MinidumpFile &File = **ExpectedFile;
+
+  ASSERT_EQ(3u, File.streams().size());
+
+  EXPECT_EQ(StreamType::SystemInfo, File.streams()[0].Type);
+  auto ExpectedSysInfo = File.getSystemInfo();
+  ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
+  const SystemInfo &SysInfo = *ExpectedSysInfo;
+  EXPECT_EQ(ProcessorArchitecture::ARM64, SysInfo.ProcessorArch);
+  EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
+  EXPECT_EQ(0x05060708u, SysInfo.CPU.Arm.CPUID);
+
+  EXPECT_EQ(StreamType::LinuxMaps, File.streams()[1].Type);
+  EXPECT_EQ("400d9000-400db000 r-xp 00000000 b3:04 227        "
+            "/system/bin/app_process\n"
+            "400db000-400dc000 r--p 00001000 b3:04 227        "
+            "/system/bin/app_process\n",
+            toStringRef(*File.getRawStream(StreamType::LinuxMaps)));
+
+  EXPECT_EQ(StreamType::LinuxAuxv, File.streams()[2].Type);
+  EXPECT_EQ((ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D}),
+            File.getRawStream(StreamType::LinuxAuxv));
+}
+
+TEST(MinidumpYAML, RawContent) {
+  SmallString<0> Storage;
+  auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+  - Type:            LinuxAuxv
+    Size:            9
+    Content:         DEADBEEFBAADF00D)");
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  object::MinidumpFile &File = **ExpectedFile;
+
+  EXPECT_EQ(
+      (ArrayRef<uint8_t>{0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, 0xF0, 0x0D, 0x00}),
+      File.getRawStream(StreamType::LinuxAuxv));
+}
+
+TEST(MinidumpYAML, X86SystemInfo) {
+  SmallString<0> Storage;
+  auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+  - Type:            SystemInfo
+    Processor Arch:  X86
+    Platform ID:     Linux
+    CPU:
+      Vendor ID:       LLVMLLVMLLVM
+      Version Info:    0x01020304
+      Feature Info:    0x05060708
+      AMD Extended Features: 0x09000102)");
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  object::MinidumpFile &File = **ExpectedFile;
+
+  ASSERT_EQ(1u, File.streams().size());
+
+  auto ExpectedSysInfo = File.getSystemInfo();
+  ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
+  const SystemInfo &SysInfo = *ExpectedSysInfo;
+  EXPECT_EQ(ProcessorArchitecture::X86, SysInfo.ProcessorArch);
+  EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
+  EXPECT_EQ("LLVMLLVMLLVM", StringRef(SysInfo.CPU.X86.VendorID,
+                                      sizeof(SysInfo.CPU.X86.VendorID)));
+  EXPECT_EQ(0x01020304u, SysInfo.CPU.X86.VersionInfo);
+  EXPECT_EQ(0x05060708u, SysInfo.CPU.X86.FeatureInfo);
+  EXPECT_EQ(0x09000102u, SysInfo.CPU.X86.AMDExtendedFeatures);
+}
+
+TEST(MinidumpYAML, OtherSystemInfo) {
+  SmallString<0> Storage;
+  auto ExpectedFile = toBinary(Storage, R"(
+--- !minidump
+Streams:
+  - Type:            SystemInfo
+    Processor Arch:  PPC
+    Platform ID:     Linux
+    CPU:
+      Features:        000102030405060708090a0b0c0d0e0f)");
+  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+  object::MinidumpFile &File = **ExpectedFile;
+
+  ASSERT_EQ(1u, File.streams().size());
+
+  auto ExpectedSysInfo = File.getSystemInfo();
+  ASSERT_THAT_EXPECTED(ExpectedSysInfo, Succeeded());
+  const SystemInfo &SysInfo = *ExpectedSysInfo;
+  EXPECT_EQ(ProcessorArchitecture::PPC, SysInfo.ProcessorArch);
+  EXPECT_EQ(OSPlatform::Linux, SysInfo.PlatformId);
+  EXPECT_EQ(
+      (ArrayRef<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),
+      makeArrayRef(SysInfo.CPU.Other.ProcessorFeatures));
+}
diff --git a/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp b/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp
index 606e160..3d283a0 100644
--- a/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp
+++ b/src/llvm-project/llvm/unittests/ObjectYAML/YAMLTest.cpp
@@ -1,9 +1,8 @@
 //===- YAMLTest.cpp - Tests for Object YAML -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/OptRemarks/CMakeLists.txt b/src/llvm-project/llvm/unittests/OptRemarks/CMakeLists.txt
deleted file mode 100644
index 94c7486..0000000
--- a/src/llvm-project/llvm/unittests/OptRemarks/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  OptRemarks
-  Support
-  )
-
-add_llvm_unittest(OptRemarksTests
-  OptRemarksParsingTest.cpp
-  )
diff --git a/src/llvm-project/llvm/unittests/OptRemarks/OptRemarksParsingTest.cpp b/src/llvm-project/llvm/unittests/OptRemarks/OptRemarksParsingTest.cpp
deleted file mode 100644
index a3b28f0..0000000
--- a/src/llvm-project/llvm/unittests/OptRemarks/OptRemarksParsingTest.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-//===- unittest/Support/OptRemarksParsingTest.cpp - OptTable tests --------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm-c/OptRemarks.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-template <size_t N> bool tryParse(const char (&Buf)[N]) {
-  LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
-  LLVMOptRemarkEntry *Remark = nullptr;
-  while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
-    EXPECT_TRUE(Remark == nullptr); // Only one remark per test.
-    Remark = NewRemark;
-  }
-  EXPECT_TRUE(Remark != nullptr); // We need *exactly* one remark per test.
-  bool HasError = LLVMOptRemarkParserHasError(Parser);
-  LLVMOptRemarkParserDispose(Parser);
-  return !HasError;
-}
-
-template <size_t N>
-bool parseExpectError(const char (&Buf)[N], const char *Error) {
-  LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
-  LLVMOptRemarkEntry *Remark = nullptr;
-  while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
-    EXPECT_FALSE(NewRemark);
-  }
-  EXPECT_TRUE(Remark == nullptr); // We are parsing only one malformed remark.
-  EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
-  bool MatchesError =
-      StringRef(LLVMOptRemarkParserGetErrorMessage(Parser)).contains(Error);
-  LLVMOptRemarkParserDispose(Parser);
-
-  return MatchesError;
-}
-
-TEST(OptRemarks, OptRemarksParsingEmpty) {
-  StringRef Buf = "\n"
-                  "\n";
-  LLVMOptRemarkParserRef Parser =
-      LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
-  LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser);
-  EXPECT_TRUE(NewRemark == nullptr); // No remark expected.
-  EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
-  EXPECT_TRUE(StringRef(LLVMOptRemarkParserGetErrorMessage(Parser))
-                  .contains("document root is not of mapping type."));
-  LLVMOptRemarkParserDispose(Parser);
-}
-
-TEST(OptRemarks, OptRemarksParsingGood) {
-  EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
-"Function: foo\n"
-"Args:\n"
-"  - Callee: bar\n"
-"  - String: ' will not be inlined into '\n"
-"  - Caller: foo\n"
-"    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-"  - String: ' because its definition is unavailable'\n"
-""));
-
-  // No debug loc should also pass.
-  EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-"  - Callee: bar\n"
-"  - String: ' will not be inlined into '\n"
-"  - Caller: foo\n"
-"    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-"  - String: ' because its definition is unavailable'\n"
-""));
-
-  // No args is also ok.
-  EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
-"Function: foo\n"
-""));
-
-  // Different order.
-  EXPECT_TRUE(tryParse("\n"
-"--- !Missed\n"
-"DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
-"Function: foo\n"
-"Name: NoDefinition\n"
-"Args:\n"
-"  - Callee: bar\n"
-"  - String: ' will not be inlined into '\n"
-"  - Caller: foo\n"
-"    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-"  - String: ' because its definition is unavailable'\n"
-"Pass: inline\n"
-""));
-}
-
-// Mandatory common part of a remark.
-#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
-// Test all the types.
-TEST(OptRemarks, OptRemarksParsingTypes) {
-  // Type: Passed
-  EXPECT_TRUE(tryParse("--- !Passed" COMMON_REMARK));
-  // Type: Missed
-  EXPECT_TRUE(tryParse("--- !Missed" COMMON_REMARK));
-  // Type: Analysis
-  EXPECT_TRUE(tryParse("--- !Analysis" COMMON_REMARK));
-  // Type: AnalysisFPCompute
-  EXPECT_TRUE(tryParse("--- !AnalysisFPCompute" COMMON_REMARK));
-  // Type: AnalysisAliasing
-  EXPECT_TRUE(tryParse("--- !AnalysisAliasing" COMMON_REMARK));
-  // Type: Failure
-  EXPECT_TRUE(tryParse("--- !Failure" COMMON_REMARK));
-}
-#undef COMMON_REMARK
-
-TEST(OptRemarks, OptRemarksParsingMissingFields) {
-  // No type.
-  EXPECT_TRUE(parseExpectError("\n"
-"---\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
-                               "error: Type, Pass, Name or Function missing."));
-  // No pass.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
-                               "error: Type, Pass, Name or Function missing."));
-  // No name.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Function: foo\n"
-"",
-                               "error: Type, Pass, Name or Function missing."));
-  // No function.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"",
-                               "error: Type, Pass, Name or Function missing."));
-  // Debug loc but no file.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { Line: 3, Column: 12 }\n"
-"",
-                               "DebugLoc node incomplete."));
-  // Debug loc but no line.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12 }\n"
-"",
-                               "DebugLoc node incomplete."));
-  // Debug loc but no column.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Line: 3 }\n"
-"",
-                               "DebugLoc node incomplete."));
-}
-
-TEST(OptRemarks, OptRemarksParsingWrongTypes) {
-  // Wrong debug loc type.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: foo\n"
-"",
-                               "expected a value of mapping type."));
-  // Wrong line type.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
-"",
-                               "expected a value of integer type."));
-  // Wrong column type.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Line: 3, Column: c }\n"
-"",
-                               "expected a value of integer type."));
-  // Wrong args type.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args: foo\n"
-"",
-                               "wrong value type for key."));
-  // Wrong key type.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"{ A: a }: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
-                               "key is not a string."));
-  // Debug loc with unknown entry.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
-"",
-                               "unknown entry in DebugLoc map."));
-  // Unknown entry.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Unknown: inline\n"
-"",
-                               "unknown key."));
-  // Not a scalar.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: { File: a, Line: 1, Column: 2 }\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"",
-                               "expected a value of scalar type."));
-  // Not a string file in debug loc.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
-"",
-                               "expected a value of scalar type."));
-  // Not a integer column in debug loc.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
-"",
-                               "expected a value of scalar type."));
-  // Not a integer line in debug loc.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
-"",
-                               "expected a value of scalar type."));
-  // Not a mapping type value for args.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
-"",
-                               "expected a value of scalar type."));
-}
-
-TEST(OptRemarks, OptRemarksParsingWrongArgs) {
-  // Multiple debug locs per arg.
-  EXPECT_TRUE(
-      parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-"  - Str: string\n"
-"    DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"    DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
-                       "only one DebugLoc entry is allowed per argument."));
-  // Multiple strings per arg.
-  EXPECT_TRUE(
-      parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-"  - Str: string\n"
-"    Str2: string\n"
-"    DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
-                       "only one string entry is allowed per argument."));
-  // No arg value.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-"  - Callee: ''\n"
-"  - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
-                               "argument value is missing."));
-  // No arg value.
-  EXPECT_TRUE(parseExpectError("\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"Function: foo\n"
-"Args:\n"
-"  - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
-"",
-                               "argument key is missing."));
-
-}
-
-TEST(OptRemarks, OptRemarksGoodStruct) {
-  StringRef Buf = "\n"
-"--- !Missed\n"
-"Pass: inline\n"
-"Name: NoDefinition\n"
-"DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
-"Function: foo\n"
-"Args:\n"
-"  - Callee: bar\n"
-"  - String: ' will not be inlined into '\n"
-"  - Caller: foo\n"
-"    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
-"  - String: ' because its definition is unavailable'\n"
-"\n";
-
-  LLVMOptRemarkParserRef Parser =
-      LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
-  LLVMOptRemarkEntry *Remark = LLVMOptRemarkParserGetNext(Parser);
-  EXPECT_FALSE(Remark == nullptr);
-  EXPECT_EQ(StringRef(Remark->RemarkType.Str, 7), "!Missed");
-  EXPECT_EQ(Remark->RemarkType.Len, 7U);
-  EXPECT_EQ(StringRef(Remark->PassName.Str, 6), "inline");
-  EXPECT_EQ(Remark->PassName.Len, 6U);
-  EXPECT_EQ(StringRef(Remark->RemarkName.Str, 12), "NoDefinition");
-  EXPECT_EQ(Remark->RemarkName.Len, 12U);
-  EXPECT_EQ(StringRef(Remark->FunctionName.Str, 3), "foo");
-  EXPECT_EQ(Remark->FunctionName.Len, 3U);
-  EXPECT_EQ(StringRef(Remark->DebugLoc.SourceFile.Str, 6), "file.c");
-  EXPECT_EQ(Remark->DebugLoc.SourceFile.Len, 6U);
-  EXPECT_EQ(Remark->DebugLoc.SourceLineNumber, 3U);
-  EXPECT_EQ(Remark->DebugLoc.SourceColumnNumber, 12U);
-  EXPECT_EQ(Remark->Hotness, 0U);
-  EXPECT_EQ(Remark->NumArgs, 4U);
-  // Arg 0
-  {
-    LLVMOptRemarkArg &Arg = Remark->Args[0];
-    EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Callee");
-    EXPECT_EQ(Arg.Key.Len, 6U);
-    EXPECT_EQ(StringRef(Arg.Value.Str, 3), "bar");
-    EXPECT_EQ(Arg.Value.Len, 3U);
-    EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
-    EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
-    EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
-    EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
-  }
-  // Arg 1
-  {
-    LLVMOptRemarkArg &Arg = Remark->Args[1];
-    EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
-    EXPECT_EQ(Arg.Key.Len, 6U);
-    EXPECT_EQ(StringRef(Arg.Value.Str, 26), " will not be inlined into ");
-    EXPECT_EQ(Arg.Value.Len, 26U);
-    EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
-    EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
-    EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
-    EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
-  }
-  // Arg 2
-  {
-    LLVMOptRemarkArg &Arg = Remark->Args[2];
-    EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Caller");
-    EXPECT_EQ(Arg.Key.Len, 6U);
-    EXPECT_EQ(StringRef(Arg.Value.Str, 3), "foo");
-    EXPECT_EQ(Arg.Value.Len, 3U);
-    EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 6), "file.c");
-    EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 6U);
-    EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 2U);
-    EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
-  }
-  // Arg 3
-  {
-    LLVMOptRemarkArg &Arg = Remark->Args[3];
-    EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
-    EXPECT_EQ(Arg.Key.Len, 6U);
-    EXPECT_EQ(StringRef(Arg.Value.Str, 38),
-              " because its definition is unavailable");
-    EXPECT_EQ(Arg.Value.Len, 38U);
-    EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
-    EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
-    EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
-    EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
-  }
-
-  EXPECT_EQ(LLVMOptRemarkParserGetNext(Parser), nullptr);
-
-  EXPECT_FALSE(LLVMOptRemarkParserHasError(Parser));
-  LLVMOptRemarkParserDispose(Parser);
-}
diff --git a/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp b/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp
index 230049c..e1d7a47 100644
--- a/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp
+++ b/src/llvm-project/llvm/unittests/Option/OptionParsingTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -287,6 +286,10 @@
   EXPECT_EQ(Nearest, "-blorp");
   EXPECT_EQ(1U, T.findNearest("--blorm", Nearest));
   EXPECT_EQ(Nearest, "--blorp");
+  EXPECT_EQ(1U, T.findNearest("-blarg", Nearest));
+  EXPECT_EQ(Nearest, "-blarn");
+  EXPECT_EQ(1U, T.findNearest("--blarm", Nearest));
+  EXPECT_EQ(Nearest, "--blarn");
   EXPECT_EQ(1U, T.findNearest("-fjormp", Nearest));
   EXPECT_EQ(Nearest, "--fjormp");
 
@@ -295,6 +298,20 @@
   EXPECT_EQ(1U, T.findNearest("/framb:foo", Nearest));
   EXPECT_EQ(Nearest, "/cramb:foo");
 
+  // `--glormp` should have an editing distance > 0 from `--glormp=`.
+  EXPECT_GT(T.findNearest("--glorrmp", Nearest), 0U);
+  EXPECT_EQ(Nearest, "--glorrmp=");
+  EXPECT_EQ(0U, T.findNearest("--glorrmp=foo", Nearest));
+
+  // `--blurmps` should correct to `--blurmp`, not `--blurmp=`, even though
+  // both naively have an editing distance of 1.
+  EXPECT_EQ(1U, T.findNearest("--blurmps", Nearest));
+  EXPECT_EQ(Nearest, "--blurmp");
+
+  // ...but `--blurmps=foo` should correct to `--blurmp=foo`.
+  EXPECT_EQ(1U, T.findNearest("--blurmps=foo", Nearest));
+  EXPECT_EQ(Nearest, "--blurmp=foo");
+
   // Flags should be included and excluded as specified.
   EXPECT_EQ(1U, T.findNearest("-doopf", Nearest, /*FlagsToInclude=*/OptFlag2));
   EXPECT_EQ(Nearest, "-doopf2");
diff --git a/src/llvm-project/llvm/unittests/Option/Opts.td b/src/llvm-project/llvm/unittests/Option/Opts.td
index c4544b5..70920a6 100644
--- a/src/llvm-project/llvm/unittests/Option/Opts.td
+++ b/src/llvm-project/llvm/unittests/Option/Opts.td
@@ -30,9 +30,16 @@
 def SlurpJoined : Option<["-"], "slurpjoined", KIND_REMAINING_ARGS_JOINED>;
 
 def Blorp : Flag<["-", "--"], "blorp">, HelpText<"The blorp option">, Flags<[OptFlag1]>;
+def Blarn : Flag<["--", "-"], "blarn">, HelpText<"The blarn option">, Flags<[OptFlag1]>;
 def Cramb : Joined<["/"], "cramb:">, HelpText<"The cramb option">, MetaVarName<"CRAMB">, Flags<[OptFlag1]>;
 def Doopf1 : Flag<["-"], "doopf1">, HelpText<"The doopf1 option">, Flags<[OptFlag1]>;
 def Doopf2 : Flag<["-"], "doopf2">, HelpText<"The doopf2 option">, Flags<[OptFlag2]>;
 def Ermgh : Joined<["--"], "ermgh">, HelpText<"The ermgh option">, MetaVarName<"ERMGH">, Flags<[OptFlag1]>;
 def Fjormp : Flag<["--"], "fjormp">, HelpText<"The fjormp option">, Flags<[OptFlag1]>;
+
+def Glorrmp_eq : Flag<["--"], "glorrmp=">;
+
+def Blurmpq : Flag<["--"], "blurmp">;
+def Blurmpq_eq : Flag<["--"], "blurmp=">;
+
 def DashDash : Option<["--"], "", KIND_REMAINING_ARGS>;
diff --git a/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp b/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp
index abb7b57..dd889e6 100644
--- a/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Passes/PluginsTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Passes/Plugins/PluginsTest.cpp ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp b/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp
index 3dc5cdc..e0ae861 100644
--- a/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp
+++ b/src/llvm-project/llvm/unittests/Passes/TestPlugin.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Passes/Plugins/Plugin.cpp --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp b/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp
index 987f676..6b94fa1 100644
--- a/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp
+++ b/src/llvm-project/llvm/unittests/ProfileData/CoverageMappingTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp b/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp
index 2d915d4..b1e5159 100644
--- a/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp
+++ b/src/llvm-project/llvm/unittests/ProfileData/InstrProfTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/ProfileData/InstrProfTest.cpp -------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -176,7 +175,7 @@
     ASSERT_EQ(288230376151711744U, NinetyFivePerc->MinCount);
     ASSERT_EQ(72057594037927936U, NinetyNinePerc->MinCount);
   };
-  ProfileSummary &PS = Reader->getSummary();
+  ProfileSummary &PS = Reader->getSummary(/* IsCS */ false);
   VerifySummary(PS);
 
   // Test that conversion of summary to and from Metadata works.
@@ -190,8 +189,8 @@
 
   // Test that summary can be attached to and read back from module.
   Module M("my_module", Context);
-  M.setProfileSummary(MD);
-  MD = M.getProfileSummary();
+  M.setProfileSummary(MD, ProfileSummary::PSK_Instr);
+  MD = M.getProfileSummary(/* IsCS */ false);
   ASSERT_TRUE(MD);
   PSFromMD = ProfileSummary::getFromMD(MD);
   ASSERT_TRUE(PSFromMD);
@@ -802,7 +801,7 @@
   auto Profile = Writer.writeBuffer();
   readProfile(std::move(Profile));
 
-  ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
+  ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount(/* IsCS */ false));
 }
 
 TEST_P(MaybeSparseInstrProfTest, get_weighted_function_counts) {
@@ -1045,4 +1044,25 @@
 INSTANTIATE_TEST_CASE_P(MaybeSparse, MaybeSparseInstrProfTest,
                         ::testing::Bool(),);
 
+#if defined(_LP64) && defined(EXPENSIVE_CHECKS)
+TEST(ProfileReaderTest, ReadsLargeFiles) {
+  const size_t LargeSize = 1ULL << 32; // 4GB
+
+  auto RawProfile = WritableMemoryBuffer::getNewUninitMemBuffer(LargeSize);
+  if (!RawProfile)
+    return;
+  auto RawProfileReaderOrErr = InstrProfReader::create(std::move(RawProfile));
+  ASSERT_TRUE(InstrProfError::take(RawProfileReaderOrErr.takeError()) ==
+              instrprof_error::unrecognized_format);
+
+  auto IndexedProfile = WritableMemoryBuffer::getNewUninitMemBuffer(LargeSize);
+  if (!IndexedProfile)
+    return;
+  auto IndexedReaderOrErr =
+      IndexedInstrProfReader::create(std::move(IndexedProfile), nullptr);
+  ASSERT_TRUE(InstrProfError::take(IndexedReaderOrErr.takeError()) ==
+              instrprof_error::bad_magic);
+}
+#endif
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp b/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp
index f75f10b..a9a8b11 100644
--- a/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp
+++ b/src/llvm-project/llvm/unittests/ProfileData/SampleProfTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/ProfileData/SampleProfTest.cpp ------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -192,14 +191,86 @@
     delete PS;
 
     // Test that summary can be attached to and read back from module.
-    M.setProfileSummary(MD);
-    MD = M.getProfileSummary();
+    M.setProfileSummary(MD, ProfileSummary::PSK_Sample);
+    MD = M.getProfileSummary(/* IsCS */ false);
     ASSERT_TRUE(MD);
     PS = ProfileSummary::getFromMD(MD);
     ASSERT_TRUE(PS);
     VerifySummary(*PS);
     delete PS;
   }
+
+  void addFunctionSamples(StringMap<FunctionSamples> *Smap, const char *Fname,
+                          uint64_t TotalSamples, uint64_t HeadSamples) {
+    StringRef Name(Fname);
+    FunctionSamples FcnSamples;
+    FcnSamples.setName(Name);
+    FcnSamples.addTotalSamples(TotalSamples);
+    FcnSamples.addHeadSamples(HeadSamples);
+    FcnSamples.addBodySamples(1, 0, HeadSamples);
+    (*Smap)[Name] = FcnSamples;
+  }
+
+  StringMap<FunctionSamples> setupFcnSamplesForElisionTest(StringRef Policy) {
+    StringMap<FunctionSamples> Smap;
+    addFunctionSamples(&Smap, "foo", uint64_t(20301), uint64_t(1437));
+    if (Policy == "" || Policy == "all")
+      return Smap;
+    addFunctionSamples(&Smap, "foo.bar", uint64_t(20303), uint64_t(1439));
+    if (Policy == "selected")
+      return Smap;
+    addFunctionSamples(&Smap, "foo.llvm.2465", uint64_t(20305), uint64_t(1441));
+    return Smap;
+  }
+
+  void createFunctionWithSampleProfileElisionPolicy(Module *M,
+                                                    const char *Fname,
+                                                    StringRef Policy) {
+    FunctionType *FnType =
+        FunctionType::get(Type::getVoidTy(Context), {}, false);
+    auto Inserted = M->getOrInsertFunction(Fname, FnType);
+    auto Fcn = cast<Function>(Inserted.getCallee());
+    if (Policy != "")
+      Fcn->addFnAttr("sample-profile-suffix-elision-policy", Policy);
+  }
+
+  void setupModuleForElisionTest(Module *M, StringRef Policy) {
+    createFunctionWithSampleProfileElisionPolicy(M, "foo", Policy);
+    createFunctionWithSampleProfileElisionPolicy(M, "foo.bar", Policy);
+    createFunctionWithSampleProfileElisionPolicy(M, "foo.llvm.2465", Policy);
+  }
+
+  void testSuffixElisionPolicy(SampleProfileFormat Format, StringRef Policy,
+                               const StringMap<uint64_t> &Expected) {
+    SmallVector<char, 128> ProfilePath;
+    std::error_code EC;
+    EC = llvm::sys::fs::createTemporaryFile("profile", "", ProfilePath);
+    ASSERT_TRUE(NoError(EC));
+    StringRef ProfileFile(ProfilePath.data(), ProfilePath.size());
+
+    Module M("my_module", Context);
+    setupModuleForElisionTest(&M, Policy);
+    StringMap<FunctionSamples> ProfMap = setupFcnSamplesForElisionTest(Policy);
+
+    // write profile
+    createWriter(Format, ProfileFile);
+    EC = Writer->write(ProfMap);
+    ASSERT_TRUE(NoError(EC));
+    Writer->getOutputStream().flush();
+
+    // read profile
+    readProfile(M, ProfileFile);
+    EC = Reader->read();
+    ASSERT_TRUE(NoError(EC));
+
+    for (auto I = Expected.begin(); I != Expected.end(); ++I) {
+      uint64_t Esamples = uint64_t(-1);
+      FunctionSamples *Samples = Reader->getSamplesFor(I->getKey());
+      if (Samples != nullptr)
+        Esamples = Samples->getTotalSamples();
+      ASSERT_EQ(I->getValue(), Esamples);
+    }
+  }
 };
 
 TEST_F(SampleProfTest, roundtrip_text_profile) {
@@ -252,4 +323,77 @@
   ASSERT_EQ(BodySamples.get(), Max);
 }
 
+TEST_F(SampleProfTest, default_suffix_elision_text) {
+  // Default suffix elision policy: strip everything after first dot.
+  // This implies that all suffix variants will map to "foo", so
+  // we don't expect to see any entries for them in the sample
+  // profile.
+  StringMap<uint64_t> Expected;
+  Expected["foo"] = uint64_t(20301);
+  Expected["foo.bar"] = uint64_t(-1);
+  Expected["foo.llvm.2465"] = uint64_t(-1);
+  testSuffixElisionPolicy(SampleProfileFormat::SPF_Text, "", Expected);
+}
+
+TEST_F(SampleProfTest, default_suffix_elision_compact_binary) {
+  // Default suffix elision policy: strip everything after first dot.
+  // This implies that all suffix variants will map to "foo", so
+  // we don't expect to see any entries for them in the sample
+  // profile.
+  StringMap<uint64_t> Expected;
+  Expected["foo"] = uint64_t(20301);
+  Expected["foo.bar"] = uint64_t(-1);
+  Expected["foo.llvm.2465"] = uint64_t(-1);
+  testSuffixElisionPolicy(SampleProfileFormat::SPF_Compact_Binary, "",
+                          Expected);
+}
+
+TEST_F(SampleProfTest, selected_suffix_elision_text) {
+  // Profile is created and searched using the "selected"
+  // suffix elision policy: we only strip a .XXX suffix if
+  // it matches a pattern known to be generated by the compiler
+  // (e.g. ".llvm.<digits>").
+  StringMap<uint64_t> Expected;
+  Expected["foo"] = uint64_t(20301);
+  Expected["foo.bar"] = uint64_t(20303);
+  Expected["foo.llvm.2465"] = uint64_t(-1);
+  testSuffixElisionPolicy(SampleProfileFormat::SPF_Text, "selected", Expected);
+}
+
+TEST_F(SampleProfTest, selected_suffix_elision_compact_binary) {
+  // Profile is created and searched using the "selected"
+  // suffix elision policy: we only strip a .XXX suffix if
+  // it matches a pattern known to be generated by the compiler
+  // (e.g. ".llvm.<digits>").
+  StringMap<uint64_t> Expected;
+  Expected["foo"] = uint64_t(20301);
+  Expected["foo.bar"] = uint64_t(20303);
+  Expected["foo.llvm.2465"] = uint64_t(-1);
+  testSuffixElisionPolicy(SampleProfileFormat::SPF_Compact_Binary, "selected",
+                          Expected);
+}
+
+TEST_F(SampleProfTest, none_suffix_elision_text) {
+  // Profile is created and searched using the "none"
+  // suffix elision policy: no stripping of suffixes at all.
+  // Here we expect to see all variants in the profile.
+  StringMap<uint64_t> Expected;
+  Expected["foo"] = uint64_t(20301);
+  Expected["foo.bar"] = uint64_t(20303);
+  Expected["foo.llvm.2465"] = uint64_t(20305);
+  testSuffixElisionPolicy(SampleProfileFormat::SPF_Text, "none", Expected);
+}
+
+TEST_F(SampleProfTest, none_suffix_elision_compact_binary) {
+  // Profile is created and searched using the "none"
+  // suffix elision policy: no stripping of suffixes at all.
+  // Here we expect to see all variants in the profile.
+  StringMap<uint64_t> Expected;
+  Expected["foo"] = uint64_t(20301);
+  Expected["foo.bar"] = uint64_t(20303);
+  Expected["foo.llvm.2465"] = uint64_t(20305);
+  testSuffixElisionPolicy(SampleProfileFormat::SPF_Compact_Binary, "none",
+                          Expected);
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Remarks/CMakeLists.txt b/src/llvm-project/llvm/unittests/Remarks/CMakeLists.txt
new file mode 100644
index 0000000..d74960e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Remarks/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+  Remarks
+  Support
+  )
+
+add_llvm_unittest(RemarksTests
+  RemarksStrTabParsingTest.cpp
+  YAMLRemarksParsingTest.cpp
+  )
diff --git a/src/llvm-project/llvm/unittests/Remarks/RemarksStrTabParsingTest.cpp b/src/llvm-project/llvm/unittests/Remarks/RemarksStrTabParsingTest.cpp
new file mode 100644
index 0000000..f1e9eb8
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Remarks/RemarksStrTabParsingTest.cpp
@@ -0,0 +1,39 @@
+//===- unittest/Support/RemarksStrTabParsingTest.cpp - StrTab tests -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Remarks/Remark.h"
+#include "llvm/Remarks/RemarkParser.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(RemarksStrTab, ParsingEmpty) {
+  StringRef Empty("", 0);
+  remarks::ParsedStringTable StrTab(Empty);
+  Expected<StringRef> Nothing = StrTab[0];
+  EXPECT_FALSE(static_cast<bool>(Nothing));
+  EXPECT_EQ(toString(Nothing.takeError()),
+            "String with index 0 is out of bounds (size = 0).");
+}
+
+TEST(RemarksStrTab, ParsingGood) {
+  StringRef Strings("str1\0str2\0str3\0str4", 20);
+  remarks::ParsedStringTable StrTab(Strings);
+  Expected<StringRef> Result = StrTab[0];
+  EXPECT_TRUE(static_cast<bool>(Result));
+  EXPECT_EQ(*Result, "str1");
+  Result = StrTab[1];
+  EXPECT_TRUE(static_cast<bool>(Result));
+  EXPECT_EQ(*Result, "str2");
+  Result = StrTab[2];
+  EXPECT_TRUE(static_cast<bool>(Result));
+  EXPECT_EQ(*Result, "str3");
+  Result = StrTab[3];
+  EXPECT_TRUE(static_cast<bool>(Result));
+  EXPECT_EQ(*Result, "str4");
+}
diff --git a/src/llvm-project/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp b/src/llvm-project/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp
new file mode 100644
index 0000000..8b79dfd
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Remarks/YAMLRemarksParsingTest.cpp
@@ -0,0 +1,619 @@
+//===- unittest/Support/YAMLRemarksParsingTest.cpp - OptTable tests -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/Remarks.h"
+#include "llvm/Remarks/Remark.h"
+#include "llvm/Remarks/RemarkParser.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+template <size_t N> void parseGood(const char (&Buf)[N]) {
+  Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+      remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
+  EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+  EXPECT_TRUE(*MaybeParser != nullptr);
+
+  remarks::Parser &Parser = **MaybeParser;
+  Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
+  EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors.
+  EXPECT_TRUE(*Remark != nullptr);               // At least one remark.
+  Remark = Parser.next();
+  Error E = Remark.takeError();
+  EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
+  EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
+}
+
+template <size_t N>
+bool parseExpectError(const char (&Buf)[N], const char *Error) {
+  Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+      remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
+  EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+  EXPECT_TRUE(*MaybeParser != nullptr);
+
+  remarks::Parser &Parser = **MaybeParser;
+  Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
+  EXPECT_FALSE(Remark); // Check for parsing errors.
+
+  std::string ErrorStr;
+  raw_string_ostream Stream(ErrorStr);
+  handleAllErrors(Remark.takeError(),
+                  [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
+  return StringRef(Stream.str()).contains(Error);
+}
+
+TEST(YAMLRemarks, ParsingEmpty) {
+  EXPECT_TRUE(parseExpectError("\n\n", "document root is not of mapping type."));
+}
+
+TEST(YAMLRemarks, ParsingNotYAML) {
+  EXPECT_TRUE(
+      parseExpectError("\x01\x02\x03\x04\x05\x06", "Got empty plain scalar"));
+}
+
+TEST(YAMLRemarks, ParsingGood) {
+  parseGood("\n"
+            "--- !Missed\n"
+            "Pass: inline\n"
+            "Name: NoDefinition\n"
+            "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+            "Function: foo\n"
+            "Args:\n"
+            "  - Callee: bar\n"
+            "  - String: ' will not be inlined into '\n"
+            "  - Caller: foo\n"
+            "    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+            "  - String: ' because its definition is unavailable'\n"
+            "");
+
+  // No debug loc should also pass.
+  parseGood("\n"
+            "--- !Missed\n"
+            "Pass: inline\n"
+            "Name: NoDefinition\n"
+            "Function: foo\n"
+            "Args:\n"
+            "  - Callee: bar\n"
+            "  - String: ' will not be inlined into '\n"
+            "  - Caller: foo\n"
+            "    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+            "  - String: ' because its definition is unavailable'\n"
+            "");
+
+  // No args is also ok.
+  parseGood("\n"
+            "--- !Missed\n"
+            "Pass: inline\n"
+            "Name: NoDefinition\n"
+            "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+            "Function: foo\n"
+            "");
+
+  // Different order.
+  parseGood("\n"
+            "--- !Missed\n"
+            "DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
+            "Function: foo\n"
+            "Name: NoDefinition\n"
+            "Args:\n"
+            "  - Callee: bar\n"
+            "  - String: ' will not be inlined into '\n"
+            "  - Caller: foo\n"
+            "    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+            "  - String: ' because its definition is unavailable'\n"
+            "Pass: inline\n"
+            "");
+}
+
+// Mandatory common part of a remark.
+#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
+// Test all the types.
+TEST(YAMLRemarks, ParsingTypes) {
+  // Type: Passed
+  parseGood("--- !Passed" COMMON_REMARK);
+  // Type: Missed
+  parseGood("--- !Missed" COMMON_REMARK);
+  // Type: Analysis
+  parseGood("--- !Analysis" COMMON_REMARK);
+  // Type: AnalysisFPCommute
+  parseGood("--- !AnalysisFPCommute" COMMON_REMARK);
+  // Type: AnalysisAliasing
+  parseGood("--- !AnalysisAliasing" COMMON_REMARK);
+  // Type: Failure
+  parseGood("--- !Failure" COMMON_REMARK);
+}
+#undef COMMON_REMARK
+
+TEST(YAMLRemarks, ParsingMissingFields) {
+  // No type.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "---\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "",
+                   "expected a remark tag."));
+  // No pass.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "",
+                   "Type, Pass, Name or Function missing."));
+  // No name.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Function: foo\n"
+                   "",
+                   "Type, Pass, Name or Function missing."));
+  // No function.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "",
+                   "Type, Pass, Name or Function missing."));
+  // Debug loc but no file.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { Line: 3, Column: 12 }\n"
+                   "",
+                   "DebugLoc node incomplete."));
+  // Debug loc but no line.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Column: 12 }\n"
+                   "",
+                   "DebugLoc node incomplete."));
+  // Debug loc but no column.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Line: 3 }\n"
+                   "",
+                   "DebugLoc node incomplete."));
+}
+
+TEST(YAMLRemarks, ParsingWrongTypes) {
+  // Wrong debug loc type.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: foo\n"
+                   "",
+                   "expected a value of mapping type."));
+  // Wrong line type.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
+                   "",
+                   "expected a value of integer type."));
+  // Wrong column type.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Line: 3, Column: c }\n"
+                   "",
+                   "expected a value of integer type."));
+  // Wrong args type.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "Args: foo\n"
+                   "",
+                   "wrong value type for key."));
+  // Wrong key type.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "{ A: a }: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "",
+                   "key is not a string."));
+  // Debug loc with unknown entry.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
+                   "",
+                   "unknown entry in DebugLoc map."));
+  // Unknown entry.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Unknown: inline\n"
+                   "",
+                   "unknown key."));
+  // Not a scalar.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: { File: a, Line: 1, Column: 2 }\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "",
+                   "expected a value of scalar type."));
+  // Not a string file in debug loc.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
+                   "",
+                   "expected a value of scalar type."));
+  // Not a integer column in debug loc.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
+                   "",
+                   "expected a value of scalar type."));
+  // Not a integer line in debug loc.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
+                   "",
+                   "expected a value of scalar type."));
+  // Not a mapping type value for args.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
+                   "",
+                   "expected a value of scalar type."));
+}
+
+TEST(YAMLRemarks, ParsingWrongArgs) {
+  // Multiple debug locs per arg.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "Args:\n"
+                   "  - Str: string\n"
+                   "    DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+                   "    DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+                   "",
+                   "only one DebugLoc entry is allowed per argument."));
+  // Multiple strings per arg.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "Args:\n"
+                   "  - Str: string\n"
+                   "    Str2: string\n"
+                   "    DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+                   "",
+                   "only one string entry is allowed per argument."));
+  // No arg value.
+  EXPECT_TRUE(parseExpectError("\n"
+                   "--- !Missed\n"
+                   "Pass: inline\n"
+                   "Name: NoDefinition\n"
+                   "Function: foo\n"
+                   "Args:\n"
+                   "  - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
+                   "",
+                   "argument key is missing."));
+}
+
+static inline StringRef checkStr(StringRef Str, unsigned ExpectedLen) {
+  const char *StrData = Str.data();
+  unsigned StrLen = Str.size();
+  EXPECT_EQ(StrLen, ExpectedLen);
+  return StringRef(StrData, StrLen);
+}
+
+TEST(YAMLRemarks, Contents) {
+  StringRef Buf = "\n"
+                  "--- !Missed\n"
+                  "Pass: inline\n"
+                  "Name: NoDefinition\n"
+                  "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+                  "Function: foo\n"
+                  "Hotness: 4\n"
+                  "Args:\n"
+                  "  - Callee: bar\n"
+                  "  - String: ' will not be inlined into '\n"
+                  "  - Caller: foo\n"
+                  "    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+                  "  - String: ' because its definition is unavailable'\n"
+                  "\n";
+
+  Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+      remarks::createRemarkParser(remarks::Format::YAML, Buf);
+  EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+  EXPECT_TRUE(*MaybeParser != nullptr);
+
+  remarks::Parser &Parser = **MaybeParser;
+  Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
+  EXPECT_FALSE(
+      errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
+  EXPECT_TRUE(*MaybeRemark != nullptr);      // At least one remark.
+
+  const remarks::Remark &Remark = **MaybeRemark;
+  EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
+  EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
+  EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
+  EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
+  EXPECT_TRUE(Remark.Loc);
+  const remarks::RemarkLocation &RL = *Remark.Loc;
+  EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+  EXPECT_EQ(RL.SourceLine, 3U);
+  EXPECT_EQ(RL.SourceColumn, 12U);
+  EXPECT_TRUE(Remark.Hotness);
+  EXPECT_EQ(*Remark.Hotness, 4U);
+  EXPECT_EQ(Remark.Args.size(), 4U);
+
+  unsigned ArgID = 0;
+  for (const remarks::Argument &Arg : Remark.Args) {
+    switch (ArgID) {
+    case 0:
+      EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
+      EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
+      EXPECT_FALSE(Arg.Loc);
+      break;
+    case 1:
+      EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+      EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
+      EXPECT_FALSE(Arg.Loc);
+      break;
+    case 2: {
+      EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
+      EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
+      EXPECT_TRUE(Arg.Loc);
+      const remarks::RemarkLocation &RL = *Arg.Loc;
+      EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+      EXPECT_EQ(RL.SourceLine, 2U);
+      EXPECT_EQ(RL.SourceColumn, 0U);
+      break;
+    }
+    case 3:
+      EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+      EXPECT_EQ(checkStr(Arg.Val, 38),
+                " because its definition is unavailable");
+      EXPECT_FALSE(Arg.Loc);
+      break;
+    default:
+      break;
+    }
+    ++ArgID;
+  }
+
+  MaybeRemark = Parser.next();
+  Error E = MaybeRemark.takeError();
+  EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
+  EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
+}
+
+static inline StringRef checkStr(LLVMRemarkStringRef Str,
+                                 unsigned ExpectedLen) {
+  const char *StrData = LLVMRemarkStringGetData(Str);
+  unsigned StrLen = LLVMRemarkStringGetLen(Str);
+  EXPECT_EQ(StrLen, ExpectedLen);
+  return StringRef(StrData, StrLen);
+}
+
+TEST(YAMLRemarks, ContentsCAPI) {
+  StringRef Buf = "\n"
+                  "--- !Missed\n"
+                  "Pass: inline\n"
+                  "Name: NoDefinition\n"
+                  "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
+                  "Function: foo\n"
+                  "Args:\n"
+                  "  - Callee: bar\n"
+                  "  - String: ' will not be inlined into '\n"
+                  "  - Caller: foo\n"
+                  "    DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
+                  "  - String: ' because its definition is unavailable'\n"
+                  "\n";
+
+  LLVMRemarkParserRef Parser =
+      LLVMRemarkParserCreateYAML(Buf.data(), Buf.size());
+  LLVMRemarkEntryRef Remark = LLVMRemarkParserGetNext(Parser);
+  EXPECT_FALSE(Remark == nullptr);
+  EXPECT_EQ(LLVMRemarkEntryGetType(Remark), LLVMRemarkTypeMissed);
+  EXPECT_EQ(checkStr(LLVMRemarkEntryGetPassName(Remark), 6), "inline");
+  EXPECT_EQ(checkStr(LLVMRemarkEntryGetRemarkName(Remark), 12), "NoDefinition");
+  EXPECT_EQ(checkStr(LLVMRemarkEntryGetFunctionName(Remark), 3), "foo");
+  LLVMRemarkDebugLocRef DL = LLVMRemarkEntryGetDebugLoc(Remark);
+  EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
+  EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 3U);
+  EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 12U);
+  EXPECT_EQ(LLVMRemarkEntryGetHotness(Remark), 0U);
+  EXPECT_EQ(LLVMRemarkEntryGetNumArgs(Remark), 4U);
+
+  unsigned ArgID = 0;
+  LLVMRemarkArgRef Arg = LLVMRemarkEntryGetFirstArg(Remark);
+  do {
+    switch (ArgID) {
+    case 0:
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Callee");
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "bar");
+      EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
+      break;
+    case 1:
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 26),
+                " will not be inlined into ");
+      EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
+      break;
+    case 2: {
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Caller");
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "foo");
+      LLVMRemarkDebugLocRef DL = LLVMRemarkArgGetDebugLoc(Arg);
+      EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
+      EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 2U);
+      EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 0U);
+      break;
+    }
+    case 3:
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
+      EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 38),
+                " because its definition is unavailable");
+      EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
+      break;
+    default:
+      break;
+    }
+    ++ArgID;
+  } while ((Arg = LLVMRemarkEntryGetNextArg(Arg, Remark)));
+
+  LLVMRemarkEntryDispose(Remark);
+
+  EXPECT_EQ(LLVMRemarkParserGetNext(Parser), nullptr);
+
+  EXPECT_FALSE(LLVMRemarkParserHasError(Parser));
+  LLVMRemarkParserDispose(Parser);
+}
+
+TEST(YAMLRemarks, ContentsStrTab) {
+  StringRef Buf = "\n"
+                  "--- !Missed\n"
+                  "Pass: 0\n"
+                  "Name: 1\n"
+                  "DebugLoc: { File: 2, Line: 3, Column: 12 }\n"
+                  "Function: 3\n"
+                  "Hotness: 4\n"
+                  "Args:\n"
+                  "  - Callee: 5\n"
+                  "  - String: 7\n"
+                  "  - Caller: 3\n"
+                  "    DebugLoc: { File: 2, Line: 2, Column: 0 }\n"
+                  "  - String: 8\n"
+                  "\n";
+
+  StringRef StrTabBuf =
+      StringRef("inline\0NoDefinition\0file.c\0foo\0Callee\0bar\0String\0 "
+                "will not be inlined into \0 because its definition is "
+                "unavailable",
+                115);
+
+  remarks::ParsedStringTable StrTab(StrTabBuf);
+  Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+      remarks::createRemarkParser(remarks::Format::YAML, Buf, &StrTab);
+  EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+  EXPECT_TRUE(*MaybeParser != nullptr);
+
+  remarks::Parser &Parser = **MaybeParser;
+  Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
+  EXPECT_FALSE(
+      errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
+  EXPECT_TRUE(*MaybeRemark != nullptr);      // At least one remark.
+
+  const remarks::Remark &Remark = **MaybeRemark;
+  EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
+  EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
+  EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
+  EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
+  EXPECT_TRUE(Remark.Loc);
+  const remarks::RemarkLocation &RL = *Remark.Loc;
+  EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+  EXPECT_EQ(RL.SourceLine, 3U);
+  EXPECT_EQ(RL.SourceColumn, 12U);
+  EXPECT_TRUE(Remark.Hotness);
+  EXPECT_EQ(*Remark.Hotness, 4U);
+  EXPECT_EQ(Remark.Args.size(), 4U);
+
+  unsigned ArgID = 0;
+  for (const remarks::Argument &Arg : Remark.Args) {
+    switch (ArgID) {
+    case 0:
+      EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
+      EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
+      EXPECT_FALSE(Arg.Loc);
+      break;
+    case 1:
+      EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+      EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
+      EXPECT_FALSE(Arg.Loc);
+      break;
+    case 2: {
+      EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
+      EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
+      EXPECT_TRUE(Arg.Loc);
+      const remarks::RemarkLocation &RL = *Arg.Loc;
+      EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
+      EXPECT_EQ(RL.SourceLine, 2U);
+      EXPECT_EQ(RL.SourceColumn, 0U);
+      break;
+    }
+    case 3:
+      EXPECT_EQ(checkStr(Arg.Key, 6), "String");
+      EXPECT_EQ(checkStr(Arg.Val, 38),
+                " because its definition is unavailable");
+      EXPECT_FALSE(Arg.Loc);
+      break;
+    default:
+      break;
+    }
+    ++ArgID;
+  }
+
+  MaybeRemark = Parser.next();
+  Error E = MaybeRemark.takeError();
+  EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
+  EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
+}
+
+TEST(YAMLRemarks, ParsingBadStringTableIndex) {
+  StringRef Buf = "\n"
+                  "--- !Missed\n"
+                  "Pass: 50\n"
+                  "\n";
+
+  StringRef StrTabBuf = StringRef("inline");
+
+  remarks::ParsedStringTable StrTab(StrTabBuf);
+  Expected<std::unique_ptr<remarks::Parser>> MaybeParser =
+      remarks::createRemarkParser(remarks::Format::YAML, Buf, &StrTab);
+  EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
+  EXPECT_TRUE(*MaybeParser != nullptr);
+
+  remarks::Parser &Parser = **MaybeParser;
+  Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
+  EXPECT_FALSE(MaybeRemark); // Expect an error here.
+
+  std::string ErrorStr;
+  raw_string_ostream Stream(ErrorStr);
+  handleAllErrors(MaybeRemark.takeError(),
+                  [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
+  EXPECT_TRUE(
+      StringRef(Stream.str())
+          .contains("String with index 50 is out of bounds (size = 1)."));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp b/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
index 9940118..6781acc 100644
--- a/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
@@ -75,6 +75,16 @@
                                ARMBuildAttrs::v6S_M));
   EXPECT_TRUE(testBuildAttr(6, 13, ARMBuildAttrs::CPU_arch,
                                ARMBuildAttrs::v7E_M));
+  EXPECT_TRUE(testBuildAttr(6, 14, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v8_A));
+  EXPECT_TRUE(testBuildAttr(6, 15, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v8_R));
+  EXPECT_TRUE(testBuildAttr(6, 16, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v8_M_Base));
+  EXPECT_TRUE(testBuildAttr(6, 17, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v8_M_Main));
+  EXPECT_TRUE(testBuildAttr(6, 21, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v8_1_M_Main));
 }
 
 TEST(CPUArchProfileBuildAttr, testBuildAttr) {
@@ -159,6 +169,16 @@
                             ARMBuildAttrs::AllowHPFP));
 }
 
+TEST(MVEBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(48, "Tag_MVE_arch"));
+  EXPECT_TRUE(testBuildAttr(48, 0, ARMBuildAttrs::MVE_arch,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(48, 1, ARMBuildAttrs::MVE_arch,
+                            ARMBuildAttrs::AllowMVEInteger));
+  EXPECT_TRUE(testBuildAttr(48, 2, ARMBuildAttrs::MVE_arch,
+                            ARMBuildAttrs::AllowMVEIntegerAndFloat));
+}
+
 TEST(CPUAlignBuildAttr, testBuildAttr) {
   EXPECT_TRUE(testTagString(34, "Tag_CPU_unaligned_access"));
   EXPECT_TRUE(testBuildAttr(34, 0, ARMBuildAttrs::CPU_unaligned_access,
diff --git a/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
index 388ca11..94c6f5a 100644
--- a/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
@@ -1,9 +1,8 @@
 //=== - llvm/unittest/Support/AlignOfTest.cpp - Alignment utility tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
index 74b394f..a0223ea 100644
--- a/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/AnnotationsTest.cpp b/src/llvm-project/llvm/unittests/Support/AnnotationsTest.cpp
new file mode 100644
index 0000000..b2970ad
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/AnnotationsTest.cpp
@@ -0,0 +1,112 @@
+//===----- unittests/AnnotationsTest.cpp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Testing/Support/Annotations.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using ::testing::ElementsAre;
+using ::testing::IsEmpty;
+
+namespace {
+llvm::Annotations::Range range(size_t Begin, size_t End) {
+  llvm::Annotations::Range R;
+  R.Begin = Begin;
+  R.End = End;
+  return R;
+}
+
+TEST(AnnotationsTest, CleanedCode) {
+  EXPECT_EQ(llvm::Annotations("foo^bar$nnn[[baz$^[[qux]]]]").code(),
+            "foobarbazqux");
+}
+
+TEST(AnnotationsTest, Points) {
+  // A single point.
+  EXPECT_EQ(llvm::Annotations("^ab").point(), 0u);
+  EXPECT_EQ(llvm::Annotations("a^b").point(), 1u);
+  EXPECT_EQ(llvm::Annotations("ab^").point(), 2u);
+
+  // Multiple points.
+  EXPECT_THAT(llvm::Annotations("^a^bc^d^").points(),
+              ElementsAre(0u, 1u, 3u, 4u));
+
+  // No points.
+  EXPECT_THAT(llvm::Annotations("ab[[cd]]").points(), IsEmpty());
+
+  // Consecutive points.
+  EXPECT_THAT(llvm::Annotations("ab^^^cd").points(), ElementsAre(2u, 2u, 2u));
+}
+
+TEST(AnnotationsTest, Ranges) {
+  // A single range.
+  EXPECT_EQ(llvm::Annotations("[[a]]bc").range(), range(0, 1));
+  EXPECT_EQ(llvm::Annotations("a[[bc]]d").range(), range(1, 3));
+  EXPECT_EQ(llvm::Annotations("ab[[cd]]").range(), range(2, 4));
+
+  // Empty range.
+  EXPECT_EQ(llvm::Annotations("[[]]ab").range(), range(0, 0));
+  EXPECT_EQ(llvm::Annotations("a[[]]b").range(), range(1, 1));
+  EXPECT_EQ(llvm::Annotations("ab[[]]").range(), range(2, 2));
+
+  // Multiple ranges.
+  EXPECT_THAT(llvm::Annotations("[[a]][[b]]cd[[ef]]ef").ranges(),
+              ElementsAre(range(0, 1), range(1, 2), range(4, 6)));
+
+  // No ranges.
+  EXPECT_THAT(llvm::Annotations("ab^c^defef").ranges(), IsEmpty());
+}
+
+TEST(AnnotationsTest, Nested) {
+  llvm::Annotations Annotated("a[[f^oo^bar[[b[[a]]z]]]]bcdef");
+  EXPECT_THAT(Annotated.points(), ElementsAre(2u, 4u));
+  EXPECT_THAT(Annotated.ranges(),
+              ElementsAre(range(8, 9), range(7, 10), range(1, 10)));
+}
+
+TEST(AnnotationsTest, Named) {
+  // A single named point or range.
+  EXPECT_EQ(llvm::Annotations("a$foo^b").point("foo"), 1u);
+  EXPECT_EQ(llvm::Annotations("a$foo[[b]]cdef").range("foo"), range(1, 2));
+
+  // Empty names should also work.
+  EXPECT_EQ(llvm::Annotations("a$^b").point(""), 1u);
+  EXPECT_EQ(llvm::Annotations("a$[[b]]cdef").range(""), range(1, 2));
+
+  // Multiple named points.
+  llvm::Annotations Annotated("a$p1^bcd$p2^123$p1^345");
+  EXPECT_THAT(Annotated.points(), IsEmpty());
+  EXPECT_THAT(Annotated.points("p1"), ElementsAre(1u, 7u));
+  EXPECT_EQ(Annotated.point("p2"), 4u);
+}
+
+TEST(AnnotationsTest, Errors) {
+  // Annotations use llvm_unreachable, it will only crash in debug mode.
+#ifndef NDEBUG
+  // point() and range() crash on zero or multiple ranges.
+  EXPECT_DEATH(llvm::Annotations("ab[[c]]def").point(),
+               "expected exactly one point");
+  EXPECT_DEATH(llvm::Annotations("a^b^cdef").point(),
+               "expected exactly one point");
+
+  EXPECT_DEATH(llvm::Annotations("a^bcdef").range(),
+               "expected exactly one range");
+  EXPECT_DEATH(llvm::Annotations("a[[b]]c[[d]]ef").range(),
+               "expected exactly one range");
+
+  EXPECT_DEATH(llvm::Annotations("$foo^a$foo^a").point("foo"),
+               "expected exactly one point");
+  EXPECT_DEATH(llvm::Annotations("$foo[[a]]bc$foo[[a]]").range("foo"),
+               "expected exactly one range");
+
+  // Parsing failures.
+  EXPECT_DEATH(llvm::Annotations("ff[[fdfd"), "unmatched \\[\\[");
+  EXPECT_DEATH(llvm::Annotations("ff[[fdjsfjd]]xxx]]"), "unmatched \\]\\]");
+  EXPECT_DEATH(llvm::Annotations("ff$fdsfd"), "unterminated \\$name");
+#endif
+}
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp b/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
index 1ff97ba..264cf97 100644
--- a/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
@@ -1,9 +1,8 @@
 //===--- unittest/Support/ArrayRecyclerTest.cpp ---------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
index 35a010e..5291a31 100644
--- a/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/BinaryStreamTest.cpp -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -611,6 +610,77 @@
   }
 }
 
+TEST_F(BinaryStreamTest, StreamReaderULEB128) {
+  std::vector<uint64_t> TestValues = {
+      0,                  // Zero
+      0x7F,               // One byte
+      0xFF,               // One byte, all-ones
+      0xAAAA,             // Two bytes
+      0xAAAAAAAA,         // Four bytes
+      0xAAAAAAAAAAAAAAAA, // Eight bytes
+      0xffffffffffffffff  // Eight bytess, all-ones
+  };
+
+  // Conservatively assume a 10-byte encoding for each of our LEB128s, with no
+  // alignment requirement.
+  initializeOutput(10 * TestValues.size(), 1);
+  initializeInputFromOutput(1);
+
+  for (auto &Stream : Streams) {
+    // Write fields.
+    BinaryStreamWriter Writer(*Stream.Output);
+    for (const auto &Value : TestValues)
+      ASSERT_THAT_ERROR(Writer.writeULEB128(Value), Succeeded());
+
+    // Read fields.
+    BinaryStreamReader Reader(*Stream.Input);
+    std::vector<uint64_t> Results;
+    Results.resize(TestValues.size());
+    for (unsigned I = 0; I != TestValues.size(); ++I)
+      ASSERT_THAT_ERROR(Reader.readULEB128(Results[I]), Succeeded());
+
+    for (unsigned I = 0; I != TestValues.size(); ++I)
+      EXPECT_EQ(TestValues[I], Results[I]);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderSLEB128) {
+  std::vector<int64_t> TestValues = {
+      0,                  // Zero
+      0x7F,               // One byte
+      -0x7F,              // One byte, negative
+      0xFF,               // One byte, all-ones
+      0xAAAA,             // Two bytes
+      -0xAAAA,            // Two bytes, negative
+      0xAAAAAAAA,         // Four bytes
+      -0xAAAAAAAA,        // Four bytes, negative
+      0x2AAAAAAAAAAAAAAA, // Eight bytes
+      -0x7ffffffffffffff  // Eight bytess, negative
+  };
+
+  // Conservatively assume a 10-byte encoding for each of our LEB128s, with no
+  // alignment requirement.
+  initializeOutput(10 * TestValues.size(), 1);
+  initializeInputFromOutput(1);
+
+  for (auto &Stream : Streams) {
+    // Write fields.
+    BinaryStreamWriter Writer(*Stream.Output);
+    for (const auto &Value : TestValues)
+      ASSERT_THAT_ERROR(Writer.writeSLEB128(Value), Succeeded());
+
+    // Read fields.
+    BinaryStreamReader Reader(*Stream.Input);
+    std::vector<int64_t> Results;
+    Results.resize(TestValues.size());
+    for (unsigned I = 0; I != TestValues.size(); ++I)
+      ASSERT_THAT_ERROR(Reader.readSLEB128(Results[I]), Succeeded());
+
+    for (unsigned I = 0; I != TestValues.size(); ++I)
+      EXPECT_EQ(TestValues[I], Results[I]);
+  }
+}
+
 TEST_F(BinaryStreamTest, StreamReaderObject) {
   struct Foo {
     int X;
diff --git a/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp b/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
index c1f5671..cf5cf92 100644
--- a/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/BlockFrequencyTest.cpp - BlockFrequency tests ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp b/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
index 54948ba..94626e7 100644
--- a/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/Support/BranchProbabilityTest.cpp - BranchProbability tests -=//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/CMakeLists.txt b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
index f9c877f..da2b501 100644
--- a/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
@@ -5,6 +5,7 @@
 add_llvm_unittest(SupportTests
   AlignOfTest.cpp
   AllocatorTest.cpp
+  AnnotationsTest.cpp
   ARMAttributeParser.cpp
   ArrayRecyclerTest.cpp
   BinaryStreamTest.cpp
@@ -18,6 +19,7 @@
   CommandLineTest.cpp
   CompressionTest.cpp
   ConvertUTFTest.cpp
+  CRCTest.cpp
   DataExtractorTest.cpp
   DebugTest.cpp
   DebugCounterTest.cpp
@@ -27,15 +29,18 @@
   ErrnoTest.cpp
   ErrorOrTest.cpp
   ErrorTest.cpp
+  FileCheckTest.cpp
   FileOutputBufferTest.cpp
   FormatVariadicTest.cpp
   GlobPatternTest.cpp
   Host.cpp
   ItaniumManglingCanonicalizerTest.cpp
   JSONTest.cpp
+  KnownBitsTest.cpp
   LEB128Test.cpp
   LineIteratorTest.cpp
   LockFileManagerTest.cpp
+  MatchersTest.cpp
   MD5Test.cpp
   ManagedStatic.cpp
   MathExtrasTest.cpp
@@ -83,7 +88,21 @@
 # Disable all warning for AlignOfTest.cpp,
 # as it does things intentionally, and there is no reliable way of
 # disabling all warnings for all the compilers by using pragmas.
-set_source_files_properties(AlignOfTest.cpp PROPERTIES COMPILE_FLAGS -w)
+# Don't disable on MSVC, because all incriminated warnings are already disabled
+# in source; and because we would otherwise see this warning:
+#   cl : Command line warning D9025: overriding '/W4' with '/w'
+if(NOT MSVC)
+  set_source_files_properties(AlignOfTest.cpp PROPERTIES COMPILE_FLAGS -w)
+endif()
+if(MSVC)
+  if( CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.14 )
+    # Since VS2017 15.8, the following snippet: Failed<CustomSubError>()
+    # generates a warning:
+    # \svn\llvm\utils\unittest\googlemock\include\gmock\gmock-matchers.h(186):
+    #   warning C5046: 'testing::MatcherInterface<T>::~MatcherInterface': Symbol involving type with internal linkage not defined
+    set_source_files_properties(ErrorTest.cpp PROPERTIES COMPILE_FLAGS -wd5046)
+  endif()
+endif()
 
 # ManagedStatic.cpp uses <pthread>.
 target_link_libraries(SupportTests PRIVATE LLVMTestingSupport ${LLVM_PTHREAD_LIB})
diff --git a/src/llvm-project/llvm/unittests/Support/CRCTest.cpp b/src/llvm-project/llvm/unittests/Support/CRCTest.cpp
new file mode 100644
index 0000000..71afb0a
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CRCTest.cpp
@@ -0,0 +1,29 @@
+//===- llvm/unittest/Support/CRCTest.cpp - CRC tests ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for CRC calculation functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CRC.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(CRCTest, CRC32) {
+  EXPECT_EQ(0x414FA339U,
+            llvm::crc32(
+                0, StringRef("The quick brown fox jumps over the lazy dog")));
+  // CRC-32/ISO-HDLC test vector
+  // http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat.crc-32c
+  EXPECT_EQ(0xCBF43926U, llvm::crc32(0, StringRef("123456789")));
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp b/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
index 4bc2ad1..eeffe21 100644
--- a/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
@@ -1,9 +1,8 @@
 //===- CachePruningTest.cpp -----------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/Casting.cpp b/src/llvm-project/llvm/unittests/Support/Casting.cpp
index 9a818f6..bcdaca9 100644
--- a/src/llvm-project/llvm/unittests/Support/Casting.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Casting.cpp
@@ -1,9 +1,8 @@
 //===---------- llvm/unittest/Support/Casting.cpp - Casting tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -119,6 +118,12 @@
   EXPECT_TRUE(isa<foo>(B4));
 }
 
+TEST(CastingTest, isa_and_nonnull) {
+  EXPECT_TRUE(isa_and_nonnull<foo>(B2));
+  EXPECT_TRUE(isa_and_nonnull<foo>(B4));
+  EXPECT_FALSE(isa_and_nonnull<foo>(fub()));
+}
+
 TEST(CastingTest, cast) {
   foo &F1 = cast<foo>(B1);
   EXPECT_NE(&F1, null_foo);
diff --git a/src/llvm-project/llvm/unittests/Support/Chrono.cpp b/src/llvm-project/llvm/unittests/Support/Chrono.cpp
index a6b76c8..9a08a5c 100644
--- a/src/llvm-project/llvm/unittests/Support/Chrono.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Chrono.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/Chrono.cpp - Time utilities tests ------------===//
 //
-//           The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
index 9d06f72..1a1c8a4 100644
--- a/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/CommandLineTest.cpp - CommandLine tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -14,6 +13,7 @@
 #include "llvm/Config/config.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/StringSaver.h"
@@ -95,12 +95,20 @@
   cl::Option *Retrieved = Map["test-option"];
   ASSERT_EQ(&TestOption, Retrieved) << "Retrieved wrong option.";
 
-  ASSERT_EQ(&cl::GeneralCategory,Retrieved->Category) <<
-    "Incorrect default option category.";
+  ASSERT_NE(Retrieved->Categories.end(),
+            find_if(Retrieved->Categories,
+                    [&](const llvm::cl::OptionCategory *Cat) {
+                      return Cat == &cl::GeneralCategory;
+                    }))
+      << "Incorrect default option category.";
 
-  Retrieved->setCategory(TestCategory);
-  ASSERT_EQ(&TestCategory,Retrieved->Category) <<
-    "Failed to modify option's option category.";
+  Retrieved->addCategory(TestCategory);
+  ASSERT_NE(Retrieved->Categories.end(),
+            find_if(Retrieved->Categories,
+                    [&](const llvm::cl::OptionCategory *Cat) {
+                      return Cat == &TestCategory;
+                    }))
+      << "Failed to modify option's option category.";
 
   Retrieved->setDescription(Description);
   ASSERT_STREQ(Retrieved->HelpStr.data(), Description)
@@ -152,8 +160,56 @@
 TEST(CommandLineTest, UseOptionCategory) {
   StackOption<int> TestOption2("test-option", cl::cat(TestCategory));
 
-  ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option "
-                                                  "Category.";
+  ASSERT_NE(TestOption2.Categories.end(),
+            find_if(TestOption2.Categories,
+                         [&](const llvm::cl::OptionCategory *Cat) {
+                           return Cat == &TestCategory;
+                         }))
+      << "Failed to assign Option Category.";
+}
+
+TEST(CommandLineTest, UseMultipleCategories) {
+  StackOption<int> TestOption2("test-option2", cl::cat(TestCategory),
+                               cl::cat(cl::GeneralCategory),
+                               cl::cat(cl::GeneralCategory));
+
+  // Make sure cl::GeneralCategory wasn't added twice.
+  ASSERT_EQ(TestOption2.Categories.size(), 2U);
+
+  ASSERT_NE(TestOption2.Categories.end(),
+            find_if(TestOption2.Categories,
+                         [&](const llvm::cl::OptionCategory *Cat) {
+                           return Cat == &TestCategory;
+                         }))
+      << "Failed to assign Option Category.";
+  ASSERT_NE(TestOption2.Categories.end(),
+            find_if(TestOption2.Categories,
+                         [&](const llvm::cl::OptionCategory *Cat) {
+                           return Cat == &cl::GeneralCategory;
+                         }))
+      << "Failed to assign General Category.";
+
+  cl::OptionCategory AnotherCategory("Additional test Options", "Description");
+  StackOption<int> TestOption("test-option", cl::cat(TestCategory),
+                              cl::cat(AnotherCategory));
+  ASSERT_EQ(TestOption.Categories.end(),
+            find_if(TestOption.Categories,
+                         [&](const llvm::cl::OptionCategory *Cat) {
+                           return Cat == &cl::GeneralCategory;
+                         }))
+      << "Failed to remove General Category.";
+  ASSERT_NE(TestOption.Categories.end(),
+            find_if(TestOption.Categories,
+                         [&](const llvm::cl::OptionCategory *Cat) {
+                           return Cat == &TestCategory;
+                         }))
+      << "Failed to assign Option Category.";
+  ASSERT_NE(TestOption.Categories.end(),
+            find_if(TestOption.Categories,
+                         [&](const llvm::cl::OptionCategory *Cat) {
+                           return Cat == &AnotherCategory;
+                         }))
+      << "Failed to assign Another Category.";
 }
 
 typedef void ParserFunction(StringRef Source, StringSaver &Saver,
@@ -185,7 +241,7 @@
                            array_lengthof(Output));
 }
 
-TEST(CommandLineTest, TokenizeWindowsCommandLine) {
+TEST(CommandLineTest, TokenizeWindowsCommandLine1) {
   const char Input[] = "a\\b c\\\\d e\\\\\"f g\" h\\\"i j\\\\\\\"k \"lmn\" o pqr "
                       "\"st \\\"u\" \\v";
   const char *const Output[] = { "a\\b", "c\\\\d", "e\\f g", "h\"i", "j\\\"k",
@@ -194,6 +250,13 @@
                            array_lengthof(Output));
 }
 
+TEST(CommandLineTest, TokenizeWindowsCommandLine2) {
+  const char Input[] = "clang -c -DFOO=\"\"\"ABC\"\"\" x.cpp";
+  const char *const Output[] = { "clang", "-c", "-DFOO=\"ABC\"", "x.cpp"};
+  testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input, Output,
+                           array_lengthof(Output));
+}
+
 TEST(CommandLineTest, TokenizeConfigFile1) {
   const char *Input = "\\";
   const char *const Output[] = { "\\" };
@@ -613,6 +676,68 @@
   }
 }
 
+TEST(CommandLineTest, DefaultOptions) {
+  cl::ResetCommandLineParser();
+
+  StackOption<std::string> Bar("bar", cl::sub(*cl::AllSubCommands),
+                               cl::DefaultOption);
+  StackOption<std::string, cl::alias> Bar_Alias(
+      "b", cl::desc("Alias for -bar"), cl::aliasopt(Bar), cl::DefaultOption);
+
+  StackOption<bool> Foo("foo", cl::init(false), cl::sub(*cl::AllSubCommands),
+                        cl::DefaultOption);
+  StackOption<bool, cl::alias> Foo_Alias("f", cl::desc("Alias for -foo"),
+                                         cl::aliasopt(Foo), cl::DefaultOption);
+
+  StackSubCommand SC1("sc1", "First Subcommand");
+  // Override "-b" and change type in sc1 SubCommand.
+  StackOption<bool> SC1_B("b", cl::sub(SC1), cl::init(false));
+  StackSubCommand SC2("sc2", "Second subcommand");
+  // Override "-foo" and change type in sc2 SubCommand.  Note that this does not
+  // affect "-f" alias, which continues to work correctly.
+  StackOption<std::string> SC2_Foo("foo", cl::sub(SC2));
+
+  const char *args0[] = {"prog", "-b", "args0 bar string", "-f"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(sizeof(args0) / sizeof(char *), args0,
+                                          StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(Bar == "args0 bar string");
+  EXPECT_TRUE(Foo);
+  EXPECT_FALSE(SC1_B);
+  EXPECT_TRUE(SC2_Foo.empty());
+
+  cl::ResetAllOptionOccurrences();
+
+  const char *args1[] = {"prog", "sc1", "-b", "-bar", "args1 bar string", "-f"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(sizeof(args1) / sizeof(char *), args1,
+                                          StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(Bar == "args1 bar string");
+  EXPECT_TRUE(Foo);
+  EXPECT_TRUE(SC1_B);
+  EXPECT_TRUE(SC2_Foo.empty());
+  for (auto *S : cl::getRegisteredSubcommands()) {
+    if (*S) {
+      EXPECT_EQ("sc1", S->getName());
+    }
+  }
+
+  cl::ResetAllOptionOccurrences();
+
+  const char *args2[] = {"prog", "sc2", "-b", "args2 bar string",
+                         "-f", "-foo", "foo string"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(sizeof(args2) / sizeof(char *), args2,
+                                          StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(Bar == "args2 bar string");
+  EXPECT_TRUE(Foo);
+  EXPECT_FALSE(SC1_B);
+  EXPECT_TRUE(SC2_Foo == "foo string");
+  for (auto *S : cl::getRegisteredSubcommands()) {
+    if (*S) {
+      EXPECT_EQ("sc2", S->getName());
+    }
+  }
+  cl::ResetCommandLineParser();
+}
+
 TEST(CommandLineTest, ArgumentLimit) {
   std::string args(32 * 4096, 'a');
   EXPECT_FALSE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data()));
@@ -665,7 +790,9 @@
   EXPECT_TRUE(IncludedFile.is_open());
   IncludedFile << "-option_1 -option_2\n"
                   "@incdir/resp2\n"
-                  "-option_3=abcd\n";
+                  "-option_3=abcd\n"
+                  "@incdir/resp3\n"
+                  "-option_4=efjk\n";
   IncludedFile.close();
 
   // Directory for included file.
@@ -683,6 +810,15 @@
   IncludedFile2 << "-option_23=abcd\n";
   IncludedFile2.close();
 
+  // Create second included response file of second level.
+  llvm::SmallString<128> IncludedFileName3;
+  llvm::sys::path::append(IncludedFileName3, IncDir, "resp3");
+  std::ofstream IncludedFile3(IncludedFileName3.c_str());
+  EXPECT_TRUE(IncludedFile3.is_open());
+  IncludedFile3 << "-option_31 -option_32\n";
+  IncludedFile3 << "-option_33=abcd\n";
+  IncludedFile3.close();
+
   // Prepare 'file' with reference to response file.
   SmallString<128> IncRef;
   IncRef.append(1, '@');
@@ -696,7 +832,7 @@
   bool Res = llvm::cl::ExpandResponseFiles(
                     Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true);
   EXPECT_TRUE(Res);
-  EXPECT_EQ(Argv.size(), 9U);
+  EXPECT_EQ(Argv.size(), 13U);
   EXPECT_STREQ(Argv[0], "test/test");
   EXPECT_STREQ(Argv[1], "-flag_1");
   EXPECT_STREQ(Argv[2], "-option_1");
@@ -705,14 +841,122 @@
   EXPECT_STREQ(Argv[5], "-option_22");
   EXPECT_STREQ(Argv[6], "-option_23=abcd");
   EXPECT_STREQ(Argv[7], "-option_3=abcd");
-  EXPECT_STREQ(Argv[8], "-flag_2");
+  EXPECT_STREQ(Argv[8], "-option_31");
+  EXPECT_STREQ(Argv[9], "-option_32");
+  EXPECT_STREQ(Argv[10], "-option_33=abcd");
+  EXPECT_STREQ(Argv[11], "-option_4=efjk");
+  EXPECT_STREQ(Argv[12], "-flag_2");
 
+  llvm::sys::fs::remove(IncludedFileName3);
   llvm::sys::fs::remove(IncludedFileName2);
   llvm::sys::fs::remove(IncDir);
   llvm::sys::fs::remove(IncludedFileName);
   llvm::sys::fs::remove(TestDir);
 }
 
+TEST(CommandLineTest, RecursiveResponseFiles) {
+  SmallString<128> TestDir;
+  std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
+  EXPECT_TRUE(!EC);
+
+  SmallString<128> SelfFilePath;
+  sys::path::append(SelfFilePath, TestDir, "self.rsp");
+  std::string SelfFileRef = std::string("@") + SelfFilePath.c_str();
+
+  SmallString<128> NestedFilePath;
+  sys::path::append(NestedFilePath, TestDir, "nested.rsp");
+  std::string NestedFileRef = std::string("@") + NestedFilePath.c_str();
+
+  SmallString<128> FlagFilePath;
+  sys::path::append(FlagFilePath, TestDir, "flag.rsp");
+  std::string FlagFileRef = std::string("@") + FlagFilePath.c_str();
+
+  std::ofstream SelfFile(SelfFilePath.str());
+  EXPECT_TRUE(SelfFile.is_open());
+  SelfFile << "-option_1\n";
+  SelfFile << FlagFileRef << "\n";
+  SelfFile << NestedFileRef << "\n";
+  SelfFile << SelfFileRef << "\n";
+  SelfFile.close();
+
+  std::ofstream NestedFile(NestedFilePath.str());
+  EXPECT_TRUE(NestedFile.is_open());
+  NestedFile << "-option_2\n";
+  NestedFile << FlagFileRef << "\n";
+  NestedFile << SelfFileRef << "\n";
+  NestedFile << NestedFileRef << "\n";
+  NestedFile.close();
+
+  std::ofstream FlagFile(FlagFilePath.str());
+  EXPECT_TRUE(FlagFile.is_open());
+  FlagFile << "-option_x\n";
+  FlagFile.close();
+
+  // Ensure:
+  // Recursive expansion terminates
+  // Recursive files never expand
+  // Non-recursive repeats are allowed
+  SmallVector<const char *, 4> Argv = {"test/test", SelfFileRef.c_str(),
+                                       "-option_3"};
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+#ifdef _WIN32
+  cl::TokenizerCallback Tokenizer = cl::TokenizeWindowsCommandLine;
+#else
+  cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine;
+#endif
+  bool Res = cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false);
+  EXPECT_FALSE(Res);
+
+  EXPECT_EQ(Argv.size(), 9U);
+  EXPECT_STREQ(Argv[0], "test/test");
+  EXPECT_STREQ(Argv[1], "-option_1");
+  EXPECT_STREQ(Argv[2], "-option_x");
+  EXPECT_STREQ(Argv[3], "-option_2");
+  EXPECT_STREQ(Argv[4], "-option_x");
+  EXPECT_STREQ(Argv[5], SelfFileRef.c_str());
+  EXPECT_STREQ(Argv[6], NestedFileRef.c_str());
+  EXPECT_STREQ(Argv[7], SelfFileRef.c_str());
+  EXPECT_STREQ(Argv[8], "-option_3");
+}
+
+TEST(CommandLineTest, ResponseFilesAtArguments) {
+  SmallString<128> TestDir;
+  std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
+  EXPECT_TRUE(!EC);
+
+  SmallString<128> ResponseFilePath;
+  sys::path::append(ResponseFilePath, TestDir, "test.rsp");
+
+  std::ofstream ResponseFile(ResponseFilePath.c_str());
+  EXPECT_TRUE(ResponseFile.is_open());
+  ResponseFile << "-foo" << "\n";
+  ResponseFile << "-bar" << "\n";
+  ResponseFile.close();
+
+  // Ensure we expand rsp files after lots of non-rsp arguments starting with @.
+  constexpr size_t NON_RSP_AT_ARGS = 64;
+  SmallVector<const char *, 4> Argv = {"test/test"};
+  Argv.append(NON_RSP_AT_ARGS, "@non_rsp_at_arg");
+  std::string ResponseFileRef = std::string("@") + ResponseFilePath.c_str();
+  Argv.push_back(ResponseFileRef.c_str());
+
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  bool Res = cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
+                                     false, false);
+  EXPECT_FALSE(Res);
+
+  // ASSERT instead of EXPECT to prevent potential out-of-bounds access.
+  ASSERT_EQ(Argv.size(), 1 + NON_RSP_AT_ARGS + 2);
+  size_t i = 0;
+  EXPECT_STREQ(Argv[i++], "test/test");
+  for (; i < 1 + NON_RSP_AT_ARGS; ++i)
+    EXPECT_STREQ(Argv[i], "@non_rsp_at_arg");
+  EXPECT_STREQ(Argv[i++], "-foo");
+  EXPECT_STREQ(Argv[i++], "-bar");
+}
+
 TEST(CommandLineTest, SetDefautValue) {
   cl::ResetCommandLineParser();
 
@@ -804,13 +1048,21 @@
 }
 
 TEST(CommandLineTest, PositionalEatArgsError) {
+  cl::ResetCommandLineParser();
+
   StackOption<std::string, cl::list<std::string>> PosEatArgs(
       "positional-eat-args", cl::Positional, cl::desc("<arguments>..."),
       cl::ZeroOrMore, cl::PositionalEatsArgs);
+  StackOption<std::string, cl::list<std::string>> PosEatArgs2(
+      "positional-eat-args2", cl::Positional, cl::desc("Some strings"),
+      cl::ZeroOrMore, cl::PositionalEatsArgs);
 
   const char *args[] = {"prog", "-positional-eat-args=XXXX"};
   const char *args2[] = {"prog", "-positional-eat-args=XXXX", "-foo"};
   const char *args3[] = {"prog", "-positional-eat-args", "-foo"};
+  const char *args4[] = {"prog", "-positional-eat-args",
+                         "-foo", "-positional-eat-args2",
+                         "-bar", "foo"};
 
   std::string Errs;
   raw_string_ostream OS(Errs);
@@ -819,6 +1071,12 @@
   EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, StringRef(), &OS)); OS.flush();
   EXPECT_FALSE(Errs.empty()); Errs.clear();
   EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, StringRef(), &OS)); OS.flush();
+  EXPECT_TRUE(Errs.empty()); Errs.clear();
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_TRUE(cl::ParseCommandLineOptions(6, args4, StringRef(), &OS)); OS.flush();
+  EXPECT_TRUE(PosEatArgs.size() == 1);
+  EXPECT_TRUE(PosEatArgs2.size() == 2);
   EXPECT_TRUE(Errs.empty());
 }
 
@@ -840,6 +1098,221 @@
 }
 #endif
 
+class OutputRedirector {
+public:
+  OutputRedirector(int RedirectFD)
+      : RedirectFD(RedirectFD), OldFD(dup(RedirectFD)) {
+    if (OldFD == -1 ||
+        sys::fs::createTemporaryFile("unittest-redirect", "", NewFD,
+                                     FilePath) ||
+        dup2(NewFD, RedirectFD) == -1)
+      Valid = false;
+  }
+
+  ~OutputRedirector() {
+    dup2(OldFD, RedirectFD);
+    close(OldFD);
+    close(NewFD);
+  }
+
+  SmallVector<char, 128> FilePath;
+  bool Valid = true;
+
+private:
+  int RedirectFD;
+  int OldFD;
+  int NewFD;
+};
+
+struct AutoDeleteFile {
+  SmallVector<char, 128> FilePath;
+  ~AutoDeleteFile() {
+    if (!FilePath.empty())
+      sys::fs::remove(std::string(FilePath.data(), FilePath.size()));
+  }
+};
+
+class PrintOptionInfoTest : public ::testing::Test {
+public:
+  // Return std::string because the output of a failing EXPECT check is
+  // unreadable for StringRef. It also avoids any lifetime issues.
+  template <typename... Ts> std::string runTest(Ts... OptionAttributes) {
+    outs().flush();  // flush any output from previous tests
+    AutoDeleteFile File;
+    {
+      OutputRedirector Stdout(fileno(stdout));
+      if (!Stdout.Valid)
+        return "";
+      File.FilePath = Stdout.FilePath;
+
+      StackOption<OptionValue> TestOption(Opt, cl::desc(HelpText),
+                                          OptionAttributes...);
+      printOptionInfo(TestOption, 26);
+      outs().flush();
+    }
+    auto Buffer = MemoryBuffer::getFile(File.FilePath);
+    if (!Buffer)
+      return "";
+    return Buffer->get()->getBuffer().str();
+  }
+
+  enum class OptionValue { Val };
+  const StringRef Opt = "some-option";
+  const StringRef HelpText = "some help";
+
+private:
+  // This is a workaround for cl::Option sub-classes having their
+  // printOptionInfo functions private.
+  void printOptionInfo(const cl::Option &O, size_t Width) {
+    O.printOptionInfo(Width);
+  }
+};
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithoutSentinel) {
+  std::string Output =
+      runTest(cl::ValueOptional,
+              cl::values(clEnumValN(OptionValue::Val, "v1", "desc1")));
+
+  // clang-format off
+  EXPECT_EQ(Output, ("  --" + Opt + "=<value> - " + HelpText + "\n"
+                     "    =v1                 -   desc1\n")
+                        .str());
+  // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithSentinel) {
+  std::string Output = runTest(
+      cl::ValueOptional, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
+                                    clEnumValN(OptionValue::Val, "", "")));
+
+  // clang-format off
+  EXPECT_EQ(Output,
+            ("  --" + Opt + "         - " + HelpText + "\n"
+             "  --" + Opt + "=<value> - " + HelpText + "\n"
+             "    =v1                 -   desc1\n")
+                .str());
+  // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueOptionalWithSentinelWithHelp) {
+  std::string Output = runTest(
+      cl::ValueOptional, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
+                                    clEnumValN(OptionValue::Val, "", "desc2")));
+
+  // clang-format off
+  EXPECT_EQ(Output, ("  --" + Opt + "         - " + HelpText + "\n"
+                     "  --" + Opt + "=<value> - " + HelpText + "\n"
+                     "    =v1                 -   desc1\n"
+                     "    =<empty>            -   desc2\n")
+                        .str());
+  // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoValueRequiredWithEmptyValueName) {
+  std::string Output = runTest(
+      cl::ValueRequired, cl::values(clEnumValN(OptionValue::Val, "v1", "desc1"),
+                                    clEnumValN(OptionValue::Val, "", "")));
+
+  // clang-format off
+  EXPECT_EQ(Output, ("  --" + Opt + "=<value> - " + HelpText + "\n"
+                     "    =v1                 -   desc1\n"
+                     "    =<empty>\n")
+                        .str());
+  // clang-format on
+}
+
+TEST_F(PrintOptionInfoTest, PrintOptionInfoEmptyValueDescription) {
+  std::string Output = runTest(
+      cl::ValueRequired, cl::values(clEnumValN(OptionValue::Val, "v1", "")));
+
+  // clang-format off
+  EXPECT_EQ(Output,
+            ("  --" + Opt + "=<value> - " + HelpText + "\n"
+             "    =v1\n").str());
+  // clang-format on
+}
+
+class GetOptionWidthTest : public ::testing::Test {
+public:
+  enum class OptionValue { Val };
+
+  template <typename... Ts>
+  size_t runTest(StringRef ArgName, Ts... OptionAttributes) {
+    StackOption<OptionValue> TestOption(ArgName, cl::desc("some help"),
+                                        OptionAttributes...);
+    return getOptionWidth(TestOption);
+  }
+
+private:
+  // This is a workaround for cl::Option sub-classes having their
+  // printOptionInfo
+  // functions private.
+  size_t getOptionWidth(const cl::Option &O) { return O.getOptionWidth(); }
+};
+
+TEST_F(GetOptionWidthTest, GetOptionWidthArgNameLonger) {
+  StringRef ArgName("a-long-argument-name");
+  size_t ExpectedStrSize = ("  --" + ArgName + "=<value> - ").str().size();
+  EXPECT_EQ(
+      runTest(ArgName, cl::values(clEnumValN(OptionValue::Val, "v", "help"))),
+      ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest, GetOptionWidthFirstOptionNameLonger) {
+  StringRef OptName("a-long-option-name");
+  size_t ExpectedStrSize = ("    =" + OptName + " - ").str().size();
+  EXPECT_EQ(
+      runTest("a", cl::values(clEnumValN(OptionValue::Val, OptName, "help"),
+                              clEnumValN(OptionValue::Val, "b", "help"))),
+      ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest, GetOptionWidthSecondOptionNameLonger) {
+  StringRef OptName("a-long-option-name");
+  size_t ExpectedStrSize = ("    =" + OptName + " - ").str().size();
+  EXPECT_EQ(
+      runTest("a", cl::values(clEnumValN(OptionValue::Val, "b", "help"),
+                              clEnumValN(OptionValue::Val, OptName, "help"))),
+      ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest, GetOptionWidthEmptyOptionNameLonger) {
+  size_t ExpectedStrSize = StringRef("    =<empty> - ").size();
+  // The length of a=<value> (including indentation) is actually the same as the
+  // =<empty> string, so it is impossible to distinguish via testing the case
+  // where the empty string is picked from where the option name is picked.
+  EXPECT_EQ(runTest("a", cl::values(clEnumValN(OptionValue::Val, "b", "help"),
+                                    clEnumValN(OptionValue::Val, "", "help"))),
+            ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest,
+       GetOptionWidthValueOptionalEmptyOptionWithNoDescription) {
+  StringRef ArgName("a");
+  // The length of a=<value> (including indentation) is actually the same as the
+  // =<empty> string, so it is impossible to distinguish via testing the case
+  // where the empty string is ignored from where it is not ignored.
+  // The dash will not actually be printed, but the space it would take up is
+  // included to ensure a consistent column width.
+  size_t ExpectedStrSize = ("  -" + ArgName + "=<value> - ").str().size();
+  EXPECT_EQ(runTest(ArgName, cl::ValueOptional,
+                    cl::values(clEnumValN(OptionValue::Val, "value", "help"),
+                               clEnumValN(OptionValue::Val, "", ""))),
+            ExpectedStrSize);
+}
+
+TEST_F(GetOptionWidthTest,
+       GetOptionWidthValueRequiredEmptyOptionWithNoDescription) {
+  // The length of a=<value> (including indentation) is actually the same as the
+  // =<empty> string, so it is impossible to distinguish via testing the case
+  // where the empty string is picked from where the option name is picked
+  size_t ExpectedStrSize = StringRef("    =<empty> - ").size();
+  EXPECT_EQ(runTest("a", cl::ValueRequired,
+                    cl::values(clEnumValN(OptionValue::Val, "value", "help"),
+                               clEnumValN(OptionValue::Val, "", ""))),
+            ExpectedStrSize);
+}
+
 TEST(CommandLineTest, PrefixOptions) {
   cl::ResetCommandLineParser();
 
@@ -914,4 +1387,270 @@
   EXPECT_TRUE(MacroDefs.front().compare("HAVE_FOO") == 0);
 }
 
-} // anonymous namespace
+TEST(CommandLineTest, GroupingWithValue) {
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptF("f", cl::Grouping, cl::desc("Some flag"));
+  StackOption<bool> OptB("b", cl::Grouping, cl::desc("Another flag"));
+  StackOption<bool> OptD("d", cl::Grouping, cl::ValueDisallowed,
+                         cl::desc("ValueDisallowed option"));
+  StackOption<std::string> OptV("v", cl::Grouping,
+                                cl::desc("ValueRequired option"));
+  StackOption<std::string> OptO("o", cl::Grouping, cl::ValueOptional,
+                                cl::desc("ValueOptional option"));
+
+  // Should be possible to use an option which requires a value
+  // at the end of a group.
+  const char *args1[] = {"prog", "-fv", "val1"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args1, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("val1", OptV.c_str());
+  OptV.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should not crash if it is accidentally used elsewhere in the group.
+  const char *args2[] = {"prog", "-vf", "val2"};
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+  OptV.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should allow the "opt=value" form at the end of the group
+  const char *args3[] = {"prog", "-fv=val3"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args3, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("val3", OptV.c_str());
+  OptV.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should allow assigning a value for a ValueOptional option
+  // at the end of the group
+  const char *args4[] = {"prog", "-fo=val4"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args4, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("val4", OptO.c_str());
+  OptO.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should assign an empty value if a ValueOptional option is used elsewhere
+  // in the group.
+  const char *args5[] = {"prog", "-fob"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args5, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_EQ(1, OptO.getNumOccurrences());
+  EXPECT_EQ(1, OptB.getNumOccurrences());
+  EXPECT_TRUE(OptO.empty());
+  cl::ResetAllOptionOccurrences();
+
+  // Should not allow an assignment for a ValueDisallowed option.
+  const char *args6[] = {"prog", "-fd=false"};
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(2, args6, StringRef(), &llvm::nulls()));
+}
+
+TEST(CommandLineTest, GroupingAndPrefix) {
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptF("f", cl::Grouping, cl::desc("Some flag"));
+  StackOption<bool> OptB("b", cl::Grouping, cl::desc("Another flag"));
+  StackOption<std::string> OptP("p", cl::Prefix, cl::Grouping,
+                                cl::desc("Prefix and Grouping"));
+  StackOption<std::string> OptA("a", cl::AlwaysPrefix, cl::Grouping,
+                                cl::desc("AlwaysPrefix and Grouping"));
+
+  // Should be possible to use a cl::Prefix option without grouping.
+  const char *args1[] = {"prog", "-pval1"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args1, StringRef(), &llvm::nulls()));
+  EXPECT_STREQ("val1", OptP.c_str());
+  OptP.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should be possible to pass a value in a separate argument.
+  const char *args2[] = {"prog", "-p", "val2"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+  EXPECT_STREQ("val2", OptP.c_str());
+  OptP.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // The "-opt=value" form should work, too.
+  const char *args3[] = {"prog", "-p=val3"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args3, StringRef(), &llvm::nulls()));
+  EXPECT_STREQ("val3", OptP.c_str());
+  OptP.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // All three previous cases should work the same way if an option with both
+  // cl::Prefix and cl::Grouping modifiers is used at the end of a group.
+  const char *args4[] = {"prog", "-fpval4"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args4, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("val4", OptP.c_str());
+  OptP.clear();
+  cl::ResetAllOptionOccurrences();
+
+  const char *args5[] = {"prog", "-fp", "val5"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args5, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("val5", OptP.c_str());
+  OptP.clear();
+  cl::ResetAllOptionOccurrences();
+
+  const char *args6[] = {"prog", "-fp=val6"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args6, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("val6", OptP.c_str());
+  OptP.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should assign a value even if the part after a cl::Prefix option is equal
+  // to the name of another option.
+  const char *args7[] = {"prog", "-fpb"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args7, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("b", OptP.c_str());
+  EXPECT_FALSE(OptB);
+  OptP.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should be possible to use a cl::AlwaysPrefix option without grouping.
+  const char *args8[] = {"prog", "-aval8"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args8, StringRef(), &llvm::nulls()));
+  EXPECT_STREQ("val8", OptA.c_str());
+  OptA.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should not be possible to pass a value in a separate argument.
+  const char *args9[] = {"prog", "-a", "val9"};
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(3, args9, StringRef(), &llvm::nulls()));
+  cl::ResetAllOptionOccurrences();
+
+  // With the "-opt=value" form, the "=" symbol should be preserved.
+  const char *args10[] = {"prog", "-a=val10"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args10, StringRef(), &llvm::nulls()));
+  EXPECT_STREQ("=val10", OptA.c_str());
+  OptA.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // All three previous cases should work the same way if an option with both
+  // cl::AlwaysPrefix and cl::Grouping modifiers is used at the end of a group.
+  const char *args11[] = {"prog", "-faval11"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args11, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("val11", OptA.c_str());
+  OptA.clear();
+  cl::ResetAllOptionOccurrences();
+
+  const char *args12[] = {"prog", "-fa", "val12"};
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(3, args12, StringRef(), &llvm::nulls()));
+  cl::ResetAllOptionOccurrences();
+
+  const char *args13[] = {"prog", "-fa=val13"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args13, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("=val13", OptA.c_str());
+  OptA.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Should assign a value even if the part after a cl::AlwaysPrefix option
+  // is equal to the name of another option.
+  const char *args14[] = {"prog", "-fab"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args14, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(OptF);
+  EXPECT_STREQ("b", OptA.c_str());
+  EXPECT_FALSE(OptB);
+  OptA.clear();
+  cl::ResetAllOptionOccurrences();
+}
+
+TEST(CommandLineTest, LongOptions) {
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptA("a", cl::desc("Some flag"));
+  StackOption<bool> OptBLong("long-flag", cl::desc("Some long flag"));
+  StackOption<bool, cl::alias> OptB("b", cl::desc("Alias to --long-flag"),
+                                    cl::aliasopt(OptBLong));
+  StackOption<std::string> OptAB("ab", cl::desc("Another long option"));
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  const char *args1[] = {"prog", "-a", "-ab", "val1"};
+  const char *args2[] = {"prog", "-a", "--ab", "val1"};
+  const char *args3[] = {"prog", "-ab", "--ab", "val1"};
+
+  //
+  // The following tests treat `-` and `--` the same, and always match the
+  // longest string.
+  //
+
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(4, args1, StringRef(), &OS)); OS.flush();
+  EXPECT_TRUE(OptA);
+  EXPECT_FALSE(OptBLong);
+  EXPECT_STREQ("val1", OptAB.c_str());
+  EXPECT_TRUE(Errs.empty()); Errs.clear();
+  cl::ResetAllOptionOccurrences();
+
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(4, args2, StringRef(), &OS)); OS.flush();
+  EXPECT_TRUE(OptA);
+  EXPECT_FALSE(OptBLong);
+  EXPECT_STREQ("val1", OptAB.c_str());
+  EXPECT_TRUE(Errs.empty()); Errs.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Fails because `-ab` and `--ab` are treated the same and appear more than
+  // once.  Also, `val1` is unexpected.
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(4, args3, StringRef(), &OS)); OS.flush();
+  outs()<< Errs << "\n";
+  EXPECT_FALSE(Errs.empty()); Errs.clear();
+  cl::ResetAllOptionOccurrences();
+
+  //
+  // The following tests treat `-` and `--` differently, with `-` for short, and
+  // `--` for long options.
+  //
+
+  // Fails because `-ab` is treated as `-a -b`, so `-a` is seen twice, and
+  // `val1` is unexpected.
+  EXPECT_FALSE(cl::ParseCommandLineOptions(4, args1, StringRef(),
+                                           &OS, nullptr, true)); OS.flush();
+  EXPECT_FALSE(Errs.empty()); Errs.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Works because `-a` is treated differently than `--ab`.
+  EXPECT_TRUE(cl::ParseCommandLineOptions(4, args2, StringRef(),
+                                           &OS, nullptr, true)); OS.flush();
+  EXPECT_TRUE(Errs.empty()); Errs.clear();
+  cl::ResetAllOptionOccurrences();
+
+  // Works because `-ab` is treated as `-a -b`, and `--ab` is a long option.
+  EXPECT_TRUE(cl::ParseCommandLineOptions(4, args3, StringRef(),
+                                           &OS, nullptr, true));
+  EXPECT_TRUE(OptA);
+  EXPECT_TRUE(OptBLong);
+  EXPECT_STREQ("val1", OptAB.c_str());
+  OS.flush();
+  EXPECT_TRUE(Errs.empty()); Errs.clear();
+  cl::ResetAllOptionOccurrences();
+}
+}  // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp b/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
index e9f36c5..cc7be43 100644
--- a/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/CompressionTest.cpp - Compression tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp b/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
index dd6e0df..8301972 100644
--- a/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/ConvertUTFTest.cpp - ConvertUTF tests --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
index ac531b2..d863dd0 100644
--- a/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/DJBTest.cpp b/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
index b157b96..c01bbe1 100644
--- a/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
@@ -1,9 +1,8 @@
 //===---------- llvm/unittest/Support/DJBTest.cpp -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
index 8b64552..9726a74 100644
--- a/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor tests --===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -117,4 +116,14 @@
   EXPECT_EQ(8U, offset);
 }
 
+TEST(DataExtractorTest, LEB128_error) {
+  DataExtractor DE(StringRef("\x81"), false, 8);
+  uint32_t Offset = 0;
+  EXPECT_EQ(0U, DE.getULEB128(&Offset));
+  EXPECT_EQ(0U, Offset);
+
+  Offset = 0;
+  EXPECT_EQ(0U, DE.getSLEB128(&Offset));
+  EXPECT_EQ(0U, Offset);
+}
 }
diff --git a/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp b/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
index 32bf56c..e7345b1 100644
--- a/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/DebugCounterTest.cpp -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/DebugTest.cpp b/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
index 7db91ff..e68e376 100644
--- a/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/DebugTest.cpp --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
index 50a0f1e..d1afd50 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/DynamicLibrary/DynamicLibraryTest.cpp --------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
index 370c8cb..e1c6596 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/DynamicLibrary/ExportedFuncs.cpp -------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
index e2f1cf7..8ff2c30 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/DynamicLibrary/PipSqueak.cpp -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
index b44c61d..a32c06c 100644
--- a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/DynamicLibrary/PipSqueak.h -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp b/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
index 9f938ee..1e800ff 100644
--- a/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/EndianStreamTest.cpp - EndianStream.h tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/EndianTest.cpp b/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
index c2b5572..b5e4a9c 100644
--- a/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/EndianTest.cpp - Endian.h tests ------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -201,4 +200,13 @@
   EXPECT_EQ(*big_val, *little_val);
 }
 
+TEST(Endian, PacketEndianSpecificIntegralAsEnum) {
+  enum class Test : uint16_t { ONETWO = 0x0102, TWOONE = 0x0201 };
+  unsigned char bytes[] = {0x01, 0x02};
+  using LittleTest = little_t<Test>;
+  using BigTest = big_t<Test>;
+  EXPECT_EQ(Test::TWOONE, *reinterpret_cast<LittleTest *>(bytes));
+  EXPECT_EQ(Test::ONETWO, *reinterpret_cast<BigTest *>(bytes));
+}
+
 } // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
index 701ac96..747d9dd 100644
--- a/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
@@ -1,9 +1,8 @@
 //===- ErrnoTest.cpp - Error handling unit tests --------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
index 2ffc6e5..6e5bd2e 100644
--- a/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/ErrorOrTest.cpp - ErrorOr.h tests ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
index eee2fe2..c4a9f3e 100644
--- a/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
@@ -1,9 +1,8 @@
 //===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp b/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp
new file mode 100644
index 0000000..2275d72
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp
@@ -0,0 +1,573 @@
+//===- llvm/unittest/Support/FileCheckTest.cpp - FileCheck tests --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/FileCheck.h"
+#include "gtest/gtest.h"
+#include <unordered_set>
+
+using namespace llvm;
+namespace {
+
+class FileCheckTest : public ::testing::Test {};
+
+TEST_F(FileCheckTest, Literal) {
+  // Eval returns the literal's value.
+  FileCheckExpressionLiteral Ten(10);
+  Expected<uint64_t> Value = Ten.eval();
+  EXPECT_TRUE(bool(Value));
+  EXPECT_EQ(10U, *Value);
+
+  // Max value can be correctly represented.
+  FileCheckExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
+  Value = Max.eval();
+  EXPECT_TRUE(bool(Value));
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(), *Value);
+}
+
+static std::string toString(const std::unordered_set<std::string> &Set) {
+  bool First = true;
+  std::string Str;
+  for (StringRef S : Set) {
+    Str += Twine(First ? "{" + S : ", " + S).str();
+    First = false;
+  }
+  Str += '}';
+  return Str;
+}
+
+static void
+expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames,
+                  Error Err) {
+  handleAllErrors(std::move(Err), [&](const FileCheckUndefVarError &E) {
+    ExpectedUndefVarNames.erase(E.getVarName());
+  });
+  EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
+}
+
+static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
+  expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
+}
+
+TEST_F(FileCheckTest, NumericVariable) {
+  // Undefined variable: getValue and eval fail, error returned by eval holds
+  // the name of the undefined variable and setValue does not trigger assert.
+  FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1);
+  EXPECT_EQ("FOO", FooVar.getName());
+  FileCheckNumericVariableUse FooVarUse =
+      FileCheckNumericVariableUse("FOO", &FooVar);
+  EXPECT_FALSE(FooVar.getValue());
+  Expected<uint64_t> EvalResult = FooVarUse.eval();
+  EXPECT_FALSE(EvalResult);
+  expectUndefError("FOO", EvalResult.takeError());
+  FooVar.setValue(42);
+
+  // Defined variable: getValue and eval return value set.
+  Optional<uint64_t> Value = FooVar.getValue();
+  EXPECT_TRUE(bool(Value));
+  EXPECT_EQ(42U, *Value);
+  EvalResult = FooVarUse.eval();
+  EXPECT_TRUE(bool(EvalResult));
+  EXPECT_EQ(42U, *EvalResult);
+
+  // Clearing variable: getValue and eval fail. Error returned by eval holds
+  // the name of the cleared variable.
+  FooVar.clearValue();
+  Value = FooVar.getValue();
+  EXPECT_FALSE(Value);
+  EvalResult = FooVarUse.eval();
+  EXPECT_FALSE(EvalResult);
+  expectUndefError("FOO", EvalResult.takeError());
+}
+
+uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
+
+TEST_F(FileCheckTest, Binop) {
+  FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO");
+  FooVar.setValue(42);
+  std::unique_ptr<FileCheckNumericVariableUse> FooVarUse =
+      llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
+  FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR");
+  BarVar.setValue(18);
+  std::unique_ptr<FileCheckNumericVariableUse> BarVarUse =
+      llvm::make_unique<FileCheckNumericVariableUse>("BAR", &BarVar);
+  FileCheckASTBinop Binop =
+      FileCheckASTBinop(doAdd, std::move(FooVarUse), std::move(BarVarUse));
+
+  // Defined variable: eval returns right value.
+  Expected<uint64_t> Value = Binop.eval();
+  EXPECT_TRUE(bool(Value));
+  EXPECT_EQ(60U, *Value);
+
+  // 1 undefined variable: eval fails, error contains name of undefined
+  // variable.
+  FooVar.clearValue();
+  Value = Binop.eval();
+  EXPECT_FALSE(Value);
+  expectUndefError("FOO", Value.takeError());
+
+  // 2 undefined variables: eval fails, error contains names of all undefined
+  // variables.
+  BarVar.clearValue();
+  Value = Binop.eval();
+  EXPECT_FALSE(Value);
+  expectUndefErrors({"FOO", "BAR"}, Value.takeError());
+}
+
+TEST_F(FileCheckTest, ValidVarNameStart) {
+  EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a'));
+  EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G'));
+  EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('_'));
+  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('2'));
+  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('$'));
+  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('@'));
+  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('+'));
+  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('-'));
+  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart(':'));
+}
+
+static StringRef bufferize(SourceMgr &SM, StringRef Str) {
+  std::unique_ptr<MemoryBuffer> Buffer =
+      MemoryBuffer::getMemBufferCopy(Str, "TestBuffer");
+  StringRef StrBufferRef = Buffer->getBuffer();
+  SM.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+  return StrBufferRef;
+}
+
+TEST_F(FileCheckTest, ParseVar) {
+  SourceMgr SM;
+  StringRef OrigVarName = bufferize(SM, "GoodVar42");
+  StringRef VarName = OrigVarName;
+  Expected<FileCheckPattern::VariableProperties> ParsedVarResult =
+      FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
+  EXPECT_TRUE(VarName.empty());
+  EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+  VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
+  EXPECT_TRUE(VarName.empty());
+  EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+  VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
+  EXPECT_TRUE(VarName.empty());
+  EXPECT_TRUE(ParsedVarResult->IsPseudo);
+
+  VarName = bufferize(SM, "42BadVar");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
+
+  VarName = bufferize(SM, "$@");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
+
+  VarName = OrigVarName = bufferize(SM, "B@dVar");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(VarName, OrigVarName.substr(1));
+  EXPECT_EQ(ParsedVarResult->Name, "B");
+  EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+  VarName = OrigVarName = bufferize(SM, "B$dVar");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(VarName, OrigVarName.substr(1));
+  EXPECT_EQ(ParsedVarResult->Name, "B");
+  EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+  VarName = bufferize(SM, "BadVar+");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(VarName, "+");
+  EXPECT_EQ(ParsedVarResult->Name, "BadVar");
+  EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+  VarName = bufferize(SM, "BadVar-");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(VarName, "-");
+  EXPECT_EQ(ParsedVarResult->Name, "BadVar");
+  EXPECT_FALSE(ParsedVarResult->IsPseudo);
+
+  VarName = bufferize(SM, "BadVar:");
+  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  EXPECT_TRUE(bool(ParsedVarResult));
+  EXPECT_EQ(VarName, ":");
+  EXPECT_EQ(ParsedVarResult->Name, "BadVar");
+  EXPECT_FALSE(ParsedVarResult->IsPseudo);
+}
+
+class PatternTester {
+private:
+  size_t LineNumber = 1;
+  SourceMgr SM;
+  FileCheckRequest Req;
+  FileCheckPatternContext Context;
+  FileCheckPattern P =
+      FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
+
+public:
+  PatternTester() {
+    std::vector<std::string> GlobalDefines;
+    GlobalDefines.emplace_back(std::string("#FOO=42"));
+    GlobalDefines.emplace_back(std::string("BAR=BAZ"));
+    EXPECT_FALSE(
+        errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
+    Context.createLineVariable();
+    // Call parsePattern to have @LINE defined.
+    P.parsePattern("N/A", "CHECK", SM, Req);
+    // parsePattern does not expect to be called twice for the same line and
+    // will set FixedStr and RegExStr incorrectly if it is. Therefore prepare
+    // a pattern for a different line.
+    initNextPattern();
+  }
+
+  void initNextPattern() {
+    P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
+  }
+
+  bool parseNumVarDefExpect(StringRef Expr) {
+    StringRef ExprBufferRef = bufferize(SM, Expr);
+    return errorToBool(FileCheckPattern::parseNumericVariableDefinition(
+                           ExprBufferRef, &Context, LineNumber, SM)
+                           .takeError());
+  }
+
+  bool parseSubstExpect(StringRef Expr) {
+    StringRef ExprBufferRef = bufferize(SM, Expr);
+    Optional<FileCheckNumericVariable *> DefinedNumericVariable;
+    return errorToBool(P.parseNumericSubstitutionBlock(
+                            ExprBufferRef, DefinedNumericVariable, false, SM)
+                           .takeError());
+  }
+
+  bool parsePatternExpect(StringRef Pattern) {
+    StringRef PatBufferRef = bufferize(SM, Pattern);
+    return P.parsePattern(PatBufferRef, "CHECK", SM, Req);
+  }
+
+  bool matchExpect(StringRef Buffer) {
+    StringRef BufferRef = bufferize(SM, Buffer);
+    size_t MatchLen;
+    return errorToBool(P.match(BufferRef, MatchLen, SM).takeError());
+  }
+};
+
+TEST_F(FileCheckTest, ParseNumericVariableDefinition) {
+  PatternTester Tester;
+
+  // Invalid definition of pseudo.
+  EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE"));
+
+  // Conflict with pattern variable.
+  EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR"));
+
+  // Defined variable.
+  EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO"));
+}
+
+TEST_F(FileCheckTest, ParseExpr) {
+  PatternTester Tester;
+
+  // Variable definition.
+
+  // Definition of invalid variable.
+  EXPECT_TRUE(Tester.parseSubstExpect("10VAR:"));
+  EXPECT_TRUE(Tester.parseSubstExpect("@FOO:"));
+  EXPECT_TRUE(Tester.parseSubstExpect("@LINE:"));
+
+  // Garbage after name of variable being defined.
+  EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:"));
+
+  // Variable defined to numeric expression.
+  EXPECT_TRUE(Tester.parseSubstExpect("VAR1: FOO"));
+
+  // Acceptable variable definition.
+  EXPECT_FALSE(Tester.parseSubstExpect("VAR1:"));
+  EXPECT_FALSE(Tester.parseSubstExpect("  VAR2:"));
+  EXPECT_FALSE(Tester.parseSubstExpect("VAR3  :"));
+  EXPECT_FALSE(Tester.parseSubstExpect("VAR3:  "));
+
+  // Numeric expression.
+
+  // Unacceptable variable.
+  EXPECT_TRUE(Tester.parseSubstExpect("10VAR"));
+  EXPECT_TRUE(Tester.parseSubstExpect("@FOO"));
+
+  // Only valid variable.
+  EXPECT_FALSE(Tester.parseSubstExpect("@LINE"));
+  EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
+  EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
+
+  // Use variable defined on same line.
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
+  EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR"));
+
+  // Unsupported operator.
+  EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2"));
+
+  // Missing offset operand.
+  EXPECT_TRUE(Tester.parseSubstExpect("@LINE+"));
+
+  // Valid expression.
+  EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5"));
+  EXPECT_FALSE(Tester.parseSubstExpect("FOO+4"));
+  Tester.initNextPattern();
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+FOO]]"));
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+3-FOO]]"));
+}
+
+TEST_F(FileCheckTest, ParsePattern) {
+  PatternTester Tester;
+
+  // Space in pattern variable expression.
+  EXPECT_TRUE(Tester.parsePatternExpect("[[ BAR]]"));
+
+  // Invalid variable name.
+  EXPECT_TRUE(Tester.parsePatternExpect("[[42INVALID]]"));
+
+  // Invalid pattern variable definition.
+  EXPECT_TRUE(Tester.parsePatternExpect("[[@PAT:]]"));
+  EXPECT_TRUE(Tester.parsePatternExpect("[[PAT+2:]]"));
+
+  // Collision with numeric variable.
+  EXPECT_TRUE(Tester.parsePatternExpect("[[FOO:]]"));
+
+  // Valid use of pattern variable.
+  EXPECT_FALSE(Tester.parsePatternExpect("[[BAR]]"));
+
+  // Valid pattern variable definition.
+  EXPECT_FALSE(Tester.parsePatternExpect("[[PAT:[0-9]+]]"));
+
+  // Invalid numeric expressions.
+  EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]"));
+  EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]"));
+  EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]"));
+  EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]"));
+
+  // Valid numeric expressions and numeric variable definition.
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]"));
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE+2]]"));
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#NUMVAR:]]"));
+}
+
+TEST_F(FileCheckTest, Match) {
+  PatternTester Tester;
+
+  // Check matching a definition only matches a number.
+  Tester.parsePatternExpect("[[#NUMVAR:]]");
+  EXPECT_TRUE(Tester.matchExpect("FAIL"));
+  EXPECT_FALSE(Tester.matchExpect("18"));
+
+  // Check matching the variable defined matches the correct number only
+  Tester.initNextPattern();
+  Tester.parsePatternExpect("[[#NUMVAR]] [[#NUMVAR+2]]");
+  EXPECT_TRUE(Tester.matchExpect("19 21"));
+  EXPECT_TRUE(Tester.matchExpect("18 21"));
+  EXPECT_FALSE(Tester.matchExpect("18 20"));
+
+  // Check matching a numeric expression using @LINE after match failure uses
+  // the correct value for @LINE.
+  Tester.initNextPattern();
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
+  // Ok, @LINE is 4 now.
+  EXPECT_FALSE(Tester.matchExpect("4"));
+  Tester.initNextPattern();
+  // @LINE is now 5, match with substitution failure.
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]"));
+  EXPECT_TRUE(Tester.matchExpect("FOO"));
+  Tester.initNextPattern();
+  // Check that @LINE is 6 as expected.
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
+  EXPECT_FALSE(Tester.matchExpect("6"));
+}
+
+TEST_F(FileCheckTest, Substitution) {
+  SourceMgr SM;
+  FileCheckPatternContext Context;
+  std::vector<std::string> GlobalDefines;
+  GlobalDefines.emplace_back(std::string("FOO=BAR"));
+  EXPECT_FALSE(errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
+
+  // Substitution of an undefined string variable fails and error holds that
+  // variable's name.
+  FileCheckStringSubstitution StringSubstitution =
+      FileCheckStringSubstitution(&Context, "VAR404", 42);
+  Expected<std::string> SubstValue = StringSubstitution.getResult();
+  EXPECT_FALSE(bool(SubstValue));
+  expectUndefError("VAR404", SubstValue.takeError());
+
+  // Substitutions of defined pseudo and non-pseudo numeric variables return
+  // the right value.
+  FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE");
+  LineVar.setValue(42);
+  FileCheckNumericVariable NVar = FileCheckNumericVariable("N");
+  NVar.setValue(10);
+  auto LineVarUse =
+      llvm::make_unique<FileCheckNumericVariableUse>("@LINE", &LineVar);
+  auto NVarUse = llvm::make_unique<FileCheckNumericVariableUse>("N", &NVar);
+  FileCheckNumericSubstitution SubstitutionLine = FileCheckNumericSubstitution(
+      &Context, "@LINE", std::move(LineVarUse), 12);
+  FileCheckNumericSubstitution SubstitutionN =
+      FileCheckNumericSubstitution(&Context, "N", std::move(NVarUse), 30);
+  SubstValue = SubstitutionLine.getResult();
+  EXPECT_TRUE(bool(SubstValue));
+  EXPECT_EQ("42", *SubstValue);
+  SubstValue = SubstitutionN.getResult();
+  EXPECT_TRUE(bool(SubstValue));
+  EXPECT_EQ("10", *SubstValue);
+
+  // Substitution of an undefined numeric variable fails, error holds name of
+  // undefined variable.
+  LineVar.clearValue();
+  SubstValue = SubstitutionLine.getResult();
+  EXPECT_FALSE(bool(SubstValue));
+  expectUndefError("@LINE", SubstValue.takeError());
+  NVar.clearValue();
+  SubstValue = SubstitutionN.getResult();
+  EXPECT_FALSE(bool(SubstValue));
+  expectUndefError("N", SubstValue.takeError());
+
+  // Substitution of a defined string variable returns the right value.
+  FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context, 1);
+  StringSubstitution = FileCheckStringSubstitution(&Context, "FOO", 42);
+  SubstValue = StringSubstitution.getResult();
+  EXPECT_TRUE(bool(SubstValue));
+  EXPECT_EQ("BAR", *SubstValue);
+}
+
+TEST_F(FileCheckTest, FileCheckContext) {
+  FileCheckPatternContext Cxt = FileCheckPatternContext();
+  std::vector<std::string> GlobalDefines;
+  SourceMgr SM;
+
+  // Missing equal sign.
+  GlobalDefines.emplace_back(std::string("LocalVar"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("#LocalNumVar"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+  // Empty variable name.
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("=18"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("#=18"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+  // Invalid variable name.
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("18LocalVar=18"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("#18LocalNumVar=18"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+  // Name conflict between pattern and numeric variable.
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("LocalVar=18"));
+  GlobalDefines.emplace_back(std::string("#LocalVar=36"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  Cxt = FileCheckPatternContext();
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
+  GlobalDefines.emplace_back(std::string("LocalNumVar=36"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  Cxt = FileCheckPatternContext();
+
+  // Invalid numeric value for numeric variable.
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("#LocalNumVar=x"));
+  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+  // Define local variables from command-line.
+  GlobalDefines.clear();
+  GlobalDefines.emplace_back(std::string("LocalVar=FOO"));
+  GlobalDefines.emplace_back(std::string("EmptyVar="));
+  GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
+  EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+
+  // Check defined variables are present and undefined is absent.
+  StringRef LocalVarStr = "LocalVar";
+  StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar");
+  StringRef EmptyVarStr = "EmptyVar";
+  StringRef UnknownVarStr = "UnknownVar";
+  Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
+  FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1);
+  Optional<FileCheckNumericVariable *> DefinedNumericVariable;
+  Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionAST =
+      P.parseNumericSubstitutionBlock(LocalNumVarRef, DefinedNumericVariable,
+                                      /*IsLegacyLineExpr=*/false, SM);
+  EXPECT_TRUE(bool(LocalVar));
+  EXPECT_EQ(*LocalVar, "FOO");
+  Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
+  Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
+  EXPECT_TRUE(bool(ExpressionAST));
+  Expected<uint64_t> ExpressionVal = (*ExpressionAST)->eval();
+  EXPECT_TRUE(bool(ExpressionVal));
+  EXPECT_EQ(*ExpressionVal, 18U);
+  EXPECT_TRUE(bool(EmptyVar));
+  EXPECT_EQ(*EmptyVar, "");
+  EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
+
+  // Clear local variables and check they become absent.
+  Cxt.clearLocalVars();
+  LocalVar = Cxt.getPatternVarValue(LocalVarStr);
+  EXPECT_TRUE(errorToBool(LocalVar.takeError()));
+  // Check a numeric expression's evaluation fails if called after clearing of
+  // local variables, if it was created before. This is important because local
+  // variable clearing due to --enable-var-scope happens after numeric
+  // expressions are linked to the numeric variables they use.
+  EXPECT_TRUE(errorToBool((*ExpressionAST)->eval().takeError()));
+  P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
+  ExpressionAST = P.parseNumericSubstitutionBlock(
+      LocalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+  EXPECT_TRUE(bool(ExpressionAST));
+  ExpressionVal = (*ExpressionAST)->eval();
+  EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
+  EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
+  EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
+  // Clear again because parseNumericSubstitutionBlock would have created a
+  // dummy variable and stored it in GlobalNumericVariableTable.
+  Cxt.clearLocalVars();
+
+  // Redefine global variables and check variables are defined again.
+  GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
+  GlobalDefines.emplace_back(std::string("#$GlobalNumVar=36"));
+  EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  StringRef GlobalVarStr = "$GlobalVar";
+  StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar");
+  Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
+  EXPECT_TRUE(bool(GlobalVar));
+  EXPECT_EQ(*GlobalVar, "BAR");
+  P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
+  ExpressionAST = P.parseNumericSubstitutionBlock(
+      GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+  EXPECT_TRUE(bool(ExpressionAST));
+  ExpressionVal = (*ExpressionAST)->eval();
+  EXPECT_TRUE(bool(ExpressionVal));
+  EXPECT_EQ(*ExpressionVal, 36U);
+
+  // Clear local variables and check global variables remain defined.
+  Cxt.clearLocalVars();
+  EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
+  P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
+  ExpressionAST = P.parseNumericSubstitutionBlock(
+      GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
+  EXPECT_TRUE(bool(ExpressionAST));
+  ExpressionVal = (*ExpressionAST)->eval();
+  EXPECT_TRUE(bool(ExpressionVal));
+  EXPECT_EQ(*ExpressionVal, 36U);
+}
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
index 5548595..8afc212 100644
--- a/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/FileOutputBuffer.cpp - unit tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -122,53 +121,4 @@
   // Clean up.
   ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
 }
-
-TEST(FileOutputBuffer, TestModify) {
-  // Create unique temporary directory for these tests
-  SmallString<128> TestDirectory;
-  {
-    ASSERT_NO_ERROR(
-      fs::createUniqueDirectory("FileOutputBuffer-modify", TestDirectory));
-  }
-
-  SmallString<128> File1(TestDirectory);
-  File1.append("/file");
-  // First write some data.
-  {
-    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
-      FileOutputBuffer::create(File1, 10);
-    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
-    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
-    memcpy(Buffer->getBufferStart(), "AAAAAAAAAA", 10);
-    ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
-  }
-
-  // Then re-open the file for modify and change only some bytes.
-  {
-    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
-        FileOutputBuffer::create(File1, size_t(-1), FileOutputBuffer::F_modify);
-    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
-    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
-    ASSERT_EQ(10U, Buffer->getBufferSize());
-    uint8_t *Data = Buffer->getBufferStart();
-    Data[0] = 'X';
-    Data[9] = 'X';
-    ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
-  }
-
-  // Finally, re-open the file for read and verify that it has the modified
-  // contents.
-  {
-    ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(File1);
-    ASSERT_NO_ERROR(BufferOrErr.getError());
-    std::unique_ptr<MemoryBuffer> Buffer = std::move(*BufferOrErr);
-    ASSERT_EQ(10U, Buffer->getBufferSize());
-    EXPECT_EQ(StringRef("XAAAAAAAAX"), Buffer->getBuffer());
-  }
-
-  // Clean up.
-  ASSERT_NO_ERROR(fs::remove(File1));
-  ASSERT_NO_ERROR(fs::remove(TestDirectory));
-}
-
 } // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp b/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
index 91a44ba..e9565c1 100644
--- a/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
@@ -1,9 +1,8 @@
 //===- FormatVariadicTest.cpp - Unit tests for string formatting ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
index d7016ab..113b20e 100644
--- a/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/GlobPatternTest.cpp --------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/Host.cpp b/src/llvm-project/llvm/unittests/Support/Host.cpp
index 0d257a7..ec9dd95 100644
--- a/src/llvm-project/llvm/unittests/Support/Host.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Host.cpp
@@ -1,13 +1,13 @@
 //========- unittests/Support/Host.cpp - Host.cpp tests --------------========//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Host.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/FileSystem.h"
@@ -249,6 +249,48 @@
             "tsv110");
 }
 
+#if defined(__APPLE__) || defined(_AIX)
+static bool runAndGetCommandOutput(
+    const char *ExePath, ArrayRef<llvm::StringRef> argv,
+    std::unique_ptr<char[]> &Buffer, off_t &Size) {
+  bool Success = false;
+  [ExePath, argv, &Buffer, &Size, &Success] {
+    using namespace llvm::sys;
+    SmallString<128> TestDirectory;
+    ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
+
+    SmallString<128> OutputFile(TestDirectory);
+    path::append(OutputFile, "out");
+    StringRef OutputPath = OutputFile.str();
+
+    const Optional<StringRef> Redirects[] = {
+        /*STDIN=*/None, /*STDOUT=*/OutputPath, /*STDERR=*/None};
+    int RetCode = ExecuteAndWait(ExePath, argv, /*env=*/llvm::None, Redirects);
+    ASSERT_EQ(0, RetCode);
+
+    int FD = 0;
+    ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
+    Size = ::lseek(FD, 0, SEEK_END);
+    ASSERT_NE(-1, Size);
+    ::lseek(FD, 0, SEEK_SET);
+    Buffer = llvm::make_unique<char[]>(Size);
+    ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
+    ::close(FD);
+
+    ASSERT_NO_ERROR(fs::remove(OutputPath));
+    ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+    Success = true;
+  }();
+  return Success;
+}
+
+TEST_F(HostTest, DummyRunAndGetCommandOutputUse) {
+  // Suppress defined-but-not-used warnings when the tests using the helper are
+  // disabled.
+  (void) runAndGetCommandOutput;
+}
+#endif
+
 #if defined(__APPLE__)
 TEST_F(HostTest, getMacOSHostVersion) {
   using namespace llvm::sys;
@@ -256,31 +298,14 @@
   if (!HostTriple.isMacOSX())
     return;
 
-  SmallString<128> TestDirectory;
-  ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
-  SmallString<128> OutputFile(TestDirectory);
-  path::append(OutputFile, "out");
-
   const char *SwVersPath = "/usr/bin/sw_vers";
   StringRef argv[] = {SwVersPath, "-productVersion"};
-  StringRef OutputPath = OutputFile.str();
-  const Optional<StringRef> Redirects[] = {/*STDIN=*/None,
-                                           /*STDOUT=*/OutputPath,
-                                           /*STDERR=*/None};
-  int RetCode = ExecuteAndWait(SwVersPath, argv, /*env=*/llvm::None, Redirects);
-  ASSERT_EQ(0, RetCode);
-
-  int FD = 0;
-  ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
-  off_t Size = ::lseek(FD, 0, SEEK_END);
-  ASSERT_NE(-1, Size);
-  ::lseek(FD, 0, SEEK_SET);
-  std::unique_ptr<char[]> Buffer = llvm::make_unique<char[]>(Size);
-  ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
-  ::close(FD);
+  std::unique_ptr<char[]> Buffer;
+  off_t Size;
+  ASSERT_EQ(runAndGetCommandOutput(SwVersPath, argv, Buffer, Size), true);
+  StringRef SystemVersion(Buffer.get(), Size);
 
   // Ensure that the two versions match.
-  StringRef SystemVersion(Buffer.get(), Size);
   unsigned SystemMajor, SystemMinor, SystemMicro;
   ASSERT_EQ(llvm::Triple((Twine("x86_64-apple-macos") + SystemVersion))
                 .getMacOSXVersion(SystemMajor, SystemMinor, SystemMicro),
@@ -291,8 +316,52 @@
   // Don't compare the 'Micro' version, as it's always '0' for the 'Darwin'
   // triples.
   ASSERT_EQ(std::tie(SystemMajor, SystemMinor), std::tie(HostMajor, HostMinor));
+}
+#endif
 
-  ASSERT_NO_ERROR(fs::remove(OutputPath));
-  ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+#if defined(_AIX)
+TEST_F(HostTest, AIXVersionDetect) {
+  using namespace llvm::sys;
+
+  llvm::Triple HostTriple(getProcessTriple());
+  ASSERT_EQ(HostTriple.getOS(), Triple::AIX);
+
+  llvm::Triple ConfiguredHostTriple(LLVM_HOST_TRIPLE);
+  ASSERT_EQ(ConfiguredHostTriple.getOS(), Triple::AIX);
+
+  const char *ExePath = "/usr/bin/oslevel";
+  StringRef argv[] = {ExePath};
+  std::unique_ptr<char[]> Buffer;
+  off_t Size;
+  ASSERT_EQ(runAndGetCommandOutput(ExePath, argv, Buffer, Size), true);
+  StringRef SystemVersion(Buffer.get(), Size);
+
+  unsigned SystemMajor, SystemMinor, SystemMicro;
+  llvm::Triple((Twine("powerpc-ibm-aix") + SystemVersion))
+      .getOSVersion(SystemMajor, SystemMinor, SystemMicro);
+
+  // Ensure that the host triple version (major) and release (minor) numbers,
+  // unless explicitly configured, match with those of the current system.
+  if (!ConfiguredHostTriple.getOSMajorVersion()) {
+    unsigned HostMajor, HostMinor, HostMicro;
+    HostTriple.getOSVersion(HostMajor, HostMinor, HostMicro);
+    ASSERT_EQ(std::tie(SystemMajor, SystemMinor),
+              std::tie(HostMajor, HostMinor));
+  }
+
+  llvm::Triple TargetTriple(getDefaultTargetTriple());
+  if (TargetTriple.getOS() != Triple::AIX)
+    return;
+
+  // Ensure that the target triple version (major) and release (minor) numbers
+  // match with those of the current system.
+  llvm::Triple ConfiguredTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
+  if (ConfiguredTargetTriple.getOSMajorVersion())
+    return; // The version was configured explicitly; skip.
+
+  unsigned TargetMajor, TargetMinor, TargetMicro;
+  TargetTriple.getOSVersion(TargetMajor, TargetMinor, TargetMicro);
+  ASSERT_EQ(std::tie(SystemMajor, SystemMinor),
+            std::tie(TargetMajor, TargetMinor));
 }
 #endif
diff --git a/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
index 2fd6bd8..9143289 100644
--- a/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
@@ -1,9 +1,8 @@
 //===-------------- ItaniumManglingCanonicalizerTest.cpp ------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/JSONTest.cpp b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
index 9f2d47b..14c11b1 100644
--- a/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
@@ -1,13 +1,13 @@
 //===-- JSONTest.cpp - JSON unit tests --------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/JSON.h"
+#include "llvm/Support/raw_ostream.h"
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -384,6 +384,44 @@
       << "Wrong type for Optional<T> " << V;
 }
 
+TEST(JSONTest, Stream) {
+  auto StreamStuff = [](unsigned Indent) {
+    std::string S;
+    llvm::raw_string_ostream OS(S);
+    OStream J(OS, Indent);
+    J.object([&] {
+      J.attributeArray("foo", [&] {
+        J.value(nullptr);
+        J.value(42.5);
+        J.arrayBegin();
+        J.value(43);
+        J.arrayEnd();
+      });
+      J.attributeBegin("bar");
+      J.objectBegin();
+      J.objectEnd();
+      J.attributeEnd();
+      J.attribute("baz", "xyz");
+    });
+    return OS.str();
+  };
+
+  const char *Plain = R"({"foo":[null,42.5,[43]],"bar":{},"baz":"xyz"})";
+  EXPECT_EQ(Plain, StreamStuff(0));
+  const char *Pretty = R"({
+  "foo": [
+    null,
+    42.5,
+    [
+      43
+    ]
+  ],
+  "bar": {},
+  "baz": "xyz"
+})";
+  EXPECT_EQ(Pretty, StreamStuff(2));
+}
+
 } // namespace
 } // namespace json
 } // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp b/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp
new file mode 100644
index 0000000..c2b3b12
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp
@@ -0,0 +1,130 @@
+//===- llvm/unittest/Support/KnownBitsTest.cpp - KnownBits tests ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for KnownBits functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/KnownBits.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+template<typename FnTy>
+void ForeachKnownBits(unsigned Bits, FnTy Fn) {
+  unsigned Max = 1 << Bits;
+  KnownBits Known(Bits);
+  for (unsigned Zero = 0; Zero < Max; ++Zero) {
+    for (unsigned One = 0; One < Max; ++One) {
+      Known.Zero = Zero;
+      Known.One = One;
+      if (Known.hasConflict())
+        continue;
+
+      Fn(Known);
+    }
+  }
+}
+
+template<typename FnTy>
+void ForeachNumInKnownBits(const KnownBits &Known, FnTy Fn) {
+  unsigned Bits = Known.getBitWidth();
+  unsigned Max = 1 << Bits;
+  for (unsigned N = 0; N < Max; ++N) {
+    APInt Num(Bits, N);
+    if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0)
+      continue;
+
+    Fn(Num);
+  }
+}
+
+TEST(KnownBitsTest, AddCarryExhaustive) {
+  unsigned Bits = 4;
+  ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
+    ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
+      ForeachKnownBits(1, [&](const KnownBits &KnownCarry) {
+        // Explicitly compute known bits of the addition by trying all
+        // possibilities.
+        KnownBits Known(Bits);
+        Known.Zero.setAllBits();
+        Known.One.setAllBits();
+        ForeachNumInKnownBits(Known1, [&](const APInt &N1) {
+          ForeachNumInKnownBits(Known2, [&](const APInt &N2) {
+            ForeachNumInKnownBits(KnownCarry, [&](const APInt &Carry) {
+              APInt Add = N1 + N2;
+              if (Carry.getBoolValue())
+                ++Add;
+
+              Known.One &= Add;
+              Known.Zero &= ~Add;
+            });
+          });
+        });
+
+        KnownBits KnownComputed = KnownBits::computeForAddCarry(
+            Known1, Known2, KnownCarry);
+        EXPECT_EQ(Known.Zero, KnownComputed.Zero);
+        EXPECT_EQ(Known.One, KnownComputed.One);
+      });
+    });
+  });
+}
+
+static void TestAddSubExhaustive(bool IsAdd) {
+  unsigned Bits = 4;
+  ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
+    ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
+      KnownBits Known(Bits), KnownNSW(Bits);
+      Known.Zero.setAllBits();
+      Known.One.setAllBits();
+      KnownNSW.Zero.setAllBits();
+      KnownNSW.One.setAllBits();
+
+      ForeachNumInKnownBits(Known1, [&](const APInt &N1) {
+        ForeachNumInKnownBits(Known2, [&](const APInt &N2) {
+          bool Overflow;
+          APInt Res;
+          if (IsAdd)
+            Res = N1.sadd_ov(N2, Overflow);
+          else
+            Res = N1.ssub_ov(N2, Overflow);
+
+          Known.One &= Res;
+          Known.Zero &= ~Res;
+
+          if (!Overflow) {
+            KnownNSW.One &= Res;
+            KnownNSW.Zero &= ~Res;
+          }
+        });
+      });
+
+      KnownBits KnownComputed = KnownBits::computeForAddSub(
+          IsAdd, /*NSW*/false, Known1, Known2);
+      EXPECT_EQ(Known.Zero, KnownComputed.Zero);
+      EXPECT_EQ(Known.One, KnownComputed.One);
+
+      // The NSW calculation is not precise, only check that it's
+      // conservatively correct.
+      KnownBits KnownNSWComputed = KnownBits::computeForAddSub(
+          IsAdd, /*NSW*/true, Known1, Known2);
+      EXPECT_TRUE(KnownNSWComputed.Zero.isSubsetOf(KnownNSW.Zero));
+      EXPECT_TRUE(KnownNSWComputed.One.isSubsetOf(KnownNSW.One));
+    });
+  });
+}
+
+TEST(KnownBitsTest, AddSubExhaustive) {
+  TestAddSubExhaustive(true);
+  TestAddSubExhaustive(false);
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp b/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
index 1c9b5db..e429279 100644
--- a/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/LEB128Test.cpp - LEB128 function tests -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp b/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
index 67f9d97..96cf37a 100644
--- a/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
@@ -1,9 +1,8 @@
 //===- LineIterator.cpp - Unit tests --------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp b/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
index 1775d05..5f1fe0f 100644
--- a/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/LockFileManagerTest.cpp - LockFileManager tests ----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/MD5Test.cpp b/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
index bac1ec2..3a24e1f 100644
--- a/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/MD5Test.cpp - MD5 tests ----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp b/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
index d3cc80c..3e9e3f5 100644
--- a/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/ManagedStatic.cpp - ManagedStatic tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/MatchersTest.cpp b/src/llvm-project/llvm/unittests/Support/MatchersTest.cpp
new file mode 100644
index 0000000..3248686
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/MatchersTest.cpp
@@ -0,0 +1,25 @@
+//===----- unittests/MatchersTest.cpp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+#include "gmock/gmock-matchers.h"
+
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::Gt;
+using ::testing::Lt;
+using ::testing::Not;
+
+namespace {
+TEST(MatchersTest, Optional) {
+  EXPECT_THAT(llvm::Optional<int>(llvm::None), Not(llvm::ValueIs(_)));
+  EXPECT_THAT(llvm::Optional<int>(10), llvm::ValueIs(10));
+  EXPECT_THAT(llvm::Optional<int>(10), llvm::ValueIs(AllOf(Lt(11), Gt(9))));
+}
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
index 694a1f2..de87714 100644
--- a/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/MathExtrasTest.cpp - math utils tests ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
index 034b2ea..2f96643 100644
--- a/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/MemoryBufferTest.cpp - MemoryBuffer tests ----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
@@ -150,11 +149,11 @@
     EXPECT_FALSE(sys::fs::openFileForRead(TestPath.c_str(), TestFD));
   }
 
-  ErrorOr<OwningBuffer> Buf =
-      MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(),
-                                     40000, // Size
-                                     80000  // Offset
-                                     );
+  ErrorOr<OwningBuffer> Buf = MemoryBuffer::getOpenFileSlice(
+      sys::fs::convertFDToNativeFile(TestFD), TestPath.c_str(),
+      40000, // Size
+      80000  // Offset
+  );
 
   std::error_code EC = Buf.getError();
   EXPECT_FALSE(EC);
diff --git a/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp b/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
index bc2fba0..af33dc3 100644
--- a/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -51,7 +50,7 @@
 public:
   MappedMemoryTest() {
     Flags = GetParam();
-    PageSize = sys::Process::getPageSize();
+    PageSize = sys::Process::getPageSizeEstimate();
   }
 
 protected:
@@ -77,9 +76,9 @@
       return true;
 
     if (M1.base() > M2.base())
-      return (unsigned char *)M2.base() + M2.size() > M1.base();
+      return (unsigned char *)M2.base() + M2.allocatedSize() > M1.base();
 
-    return (unsigned char *)M1.base() + M1.size() > M2.base();
+    return (unsigned char *)M1.base() + M1.allocatedSize() > M2.base();
   }
 
   unsigned Flags;
@@ -101,7 +100,23 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(sizeof(int), M1.size());
+  EXPECT_LE(sizeof(int), M1.allocatedSize());
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+}
+
+TEST_P(MappedMemoryTest, AllocAndReleaseHuge) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock M1 = Memory::allocateMappedMemory(
+      sizeof(int), nullptr, Flags | Memory::MF_HUGE_HINT, EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  // Test large/huge memory pages. In the worst case, 4kb pages should be
+  // returned, if large pages aren't available.
+
+  EXPECT_NE((void *)nullptr, M1.base());
+  EXPECT_LE(sizeof(int), M1.allocatedSize());
 
   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
 }
@@ -117,11 +132,11 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(16U, M1.size());
+  EXPECT_LE(16U, M1.allocatedSize());
   EXPECT_NE((void*)nullptr, M2.base());
-  EXPECT_LE(64U, M2.size());
+  EXPECT_LE(64U, M2.allocatedSize());
   EXPECT_NE((void*)nullptr, M3.base());
-  EXPECT_LE(32U, M3.size());
+  EXPECT_LE(32U, M3.allocatedSize());
 
   EXPECT_FALSE(doesOverlap(M1, M2));
   EXPECT_FALSE(doesOverlap(M2, M3));
@@ -132,7 +147,7 @@
   MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
   EXPECT_EQ(std::error_code(), EC);
   EXPECT_NE((void*)nullptr, M4.base());
-  EXPECT_LE(16U, M4.size());
+  EXPECT_LE(16U, M4.allocatedSize());
   EXPECT_FALSE(Memory::releaseMappedMemory(M4));
   EXPECT_FALSE(Memory::releaseMappedMemory(M2));
 }
@@ -149,7 +164,7 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(sizeof(int), M1.size());
+  EXPECT_LE(sizeof(int), M1.allocatedSize());
 
   int *a = (int*)M1.base();
   *a = 1;
@@ -181,11 +196,11 @@
   EXPECT_FALSE(doesOverlap(M1, M3));
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(1U * sizeof(int), M1.size());
+  EXPECT_LE(1U * sizeof(int), M1.allocatedSize());
   EXPECT_NE((void*)nullptr, M2.base());
-  EXPECT_LE(8U * sizeof(int), M2.size());
+  EXPECT_LE(8U * sizeof(int), M2.allocatedSize());
   EXPECT_NE((void*)nullptr, M3.base());
-  EXPECT_LE(4U * sizeof(int), M3.size());
+  EXPECT_LE(4U * sizeof(int), M3.allocatedSize());
 
   int *x = (int*)M1.base();
   *x = 1;
@@ -209,7 +224,7 @@
                                                 Flags, EC);
   EXPECT_EQ(std::error_code(), EC);
   EXPECT_NE((void*)nullptr, M4.base());
-  EXPECT_LE(64U * sizeof(int), M4.size());
+  EXPECT_LE(64U * sizeof(int), M4.allocatedSize());
   x = (int*)M4.base();
   *x = 4;
   EXPECT_EQ(4, *x);
@@ -240,11 +255,11 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(2U * sizeof(int), M1.size());
+  EXPECT_LE(2U * sizeof(int), M1.allocatedSize());
   EXPECT_NE((void*)nullptr, M2.base());
-  EXPECT_LE(8U * sizeof(int), M2.size());
+  EXPECT_LE(8U * sizeof(int), M2.allocatedSize());
   EXPECT_NE((void*)nullptr, M3.base());
-  EXPECT_LE(4U * sizeof(int), M3.size());
+  EXPECT_LE(4U * sizeof(int), M3.allocatedSize());
 
   EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
   EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
@@ -274,7 +289,7 @@
   MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
   EXPECT_EQ(std::error_code(), EC);
   EXPECT_NE((void*)nullptr, M4.base());
-  EXPECT_LE(16U, M4.size());
+  EXPECT_LE(16U, M4.allocatedSize());
   EXPECT_EQ(std::error_code(),
             Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
   x = (int*)M4.base();
@@ -295,11 +310,11 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(16U, M1.size());
+  EXPECT_LE(16U, M1.allocatedSize());
   EXPECT_NE((void*)nullptr, M2.base());
-  EXPECT_LE(64U, M2.size());
+  EXPECT_LE(64U, M2.allocatedSize());
   EXPECT_NE((void*)nullptr, M3.base());
-  EXPECT_LE(32U, M3.size());
+  EXPECT_LE(32U, M3.allocatedSize());
 
   EXPECT_FALSE(doesOverlap(M1, M2));
   EXPECT_FALSE(doesOverlap(M2, M3));
@@ -322,11 +337,11 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(16U, M1.size());
+  EXPECT_LE(16U, M1.allocatedSize());
   EXPECT_NE((void*)nullptr, M2.base());
-  EXPECT_LE(64U, M2.size());
+  EXPECT_LE(64U, M2.allocatedSize());
   EXPECT_NE((void*)nullptr, M3.base());
-  EXPECT_LE(32U, M3.size());
+  EXPECT_LE(32U, M3.allocatedSize());
 
   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
   EXPECT_FALSE(Memory::releaseMappedMemory(M3));
@@ -345,11 +360,11 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(16U, M1.size());
+  EXPECT_LE(16U, M1.allocatedSize());
   EXPECT_NE((void*)nullptr, M2.base());
-  EXPECT_LE(64U, M2.size());
+  EXPECT_LE(64U, M2.allocatedSize());
   EXPECT_NE((void*)nullptr, M3.base());
-  EXPECT_LE(32U, M3.size());
+  EXPECT_LE(32U, M3.allocatedSize());
 
   EXPECT_FALSE(doesOverlap(M1, M2));
   EXPECT_FALSE(doesOverlap(M2, M3));
@@ -372,11 +387,11 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(16U, M1.size());
+  EXPECT_LE(16U, M1.allocatedSize());
   EXPECT_NE((void*)nullptr, M2.base());
-  EXPECT_LE(64U, M2.size());
+  EXPECT_LE(64U, M2.allocatedSize());
   EXPECT_NE((void*)nullptr, M3.base());
-  EXPECT_LE(32U, M3.size());
+  EXPECT_LE(32U, M3.allocatedSize());
 
   EXPECT_FALSE(doesOverlap(M1, M2));
   EXPECT_FALSE(doesOverlap(M2, M3));
@@ -395,7 +410,7 @@
   EXPECT_EQ(std::error_code(), EC);
 
   EXPECT_NE((void*)nullptr, M1.base());
-  EXPECT_LE(sizeof(int), M1.size());
+  EXPECT_LE(sizeof(int), M1.allocatedSize());
 
   EXPECT_FALSE(Memory::releaseMappedMemory(M1));
 }
diff --git a/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp b/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
index 52acb6a..bbe9aa6 100644
--- a/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
+++ b/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/NativeFormatTests.cpp - formatting tests -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp b/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
index 8779a61..63c7152 100644
--- a/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/ParallelTest.cpp -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 ///
diff --git a/src/llvm-project/llvm/unittests/Support/Path.cpp b/src/llvm-project/llvm/unittests/Support/Path.cpp
index 97b77e2..ccd72d7 100644
--- a/src/llvm-project/llvm/unittests/Support/Path.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Path.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -579,6 +578,7 @@
   auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
   ASSERT_TRUE((bool)TempFileOrError);
   fs::TempFile File = std::move(*TempFileOrError);
+  ASSERT_EQ(-1, TempFileOrError->FD);
   ASSERT_FALSE((bool)File.keep(TestDirectory + "/keep"));
   ASSERT_FALSE((bool)File.discard());
   ASSERT_TRUE(fs::exists(TestDirectory + "/keep"));
@@ -590,6 +590,7 @@
   auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
   ASSERT_TRUE((bool)TempFileOrError);
   fs::TempFile File = std::move(*TempFileOrError);
+  ASSERT_EQ(-1, TempFileOrError->FD);
   ASSERT_FALSE((bool)File.discard());
   ASSERT_FALSE((bool)File.discard());
   ASSERT_FALSE(fs::exists(TestDirectory + "/keep"));
@@ -701,10 +702,18 @@
     }
   };
 
-  // We should be able to create exactly 16 temporary files.
-  for (int i = 0; i < 16; ++i)
-    EXPECT_TRUE(TryCreateTempFile());
-  EXPECT_FALSE(TryCreateTempFile());
+  // Our single-character template allows for 16 unique names. Check that
+  // calling TryCreateTempFile repeatedly results in 16 successes.
+  // Because the test depends on random numbers, it could theoretically fail.
+  // However, the probability of this happening is tiny: with 32 calls, each
+  // of which will retry up to 128 times, to not get a given digit we would
+  // have to fail at least 15 + 17 * 128 = 2191 attempts. The probability of
+  // 2191 attempts not producing a given hexadecimal digit is
+  // (1 - 1/16) ** 2191 or 3.88e-62.
+  int Successes = 0;
+  for (int i = 0; i < 32; ++i)
+    if (TryCreateTempFile()) ++Successes;
+  EXPECT_EQ(Successes, 16);
 
   for (fs::TempFile &T : TempFiles)
     cantFail(T.discard());
@@ -1075,7 +1084,7 @@
   std::error_code EC;
   StringRef Val("hello there");
   {
-    fs::mapped_file_region mfr(FileDescriptor,
+    fs::mapped_file_region mfr(fs::convertFDToNativeFile(FileDescriptor),
                                fs::mapped_file_region::readwrite, Size, 0, EC);
     ASSERT_NO_ERROR(EC);
     std::copy(Val.begin(), Val.end(), mfr.data());
@@ -1090,14 +1099,16 @@
     int FD;
     EC = fs::openFileForRead(Twine(TempPath), FD);
     ASSERT_NO_ERROR(EC);
-    fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+    fs::mapped_file_region mfr(fs::convertFDToNativeFile(FD),
+                               fs::mapped_file_region::readonly, Size, 0, EC);
     ASSERT_NO_ERROR(EC);
 
     // Verify content
     EXPECT_EQ(StringRef(mfr.const_data()), Val);
 
     // Unmap temp file
-    fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+    fs::mapped_file_region m(fs::convertFDToNativeFile(FD),
+                             fs::mapped_file_region::readonly, Size, 0, EC);
     ASSERT_NO_ERROR(EC);
     ASSERT_EQ(close(FD), 0);
   }
@@ -1493,6 +1504,85 @@
   verifyWrite(FD, "Buzz", true);
 }
 
+TEST_F(FileSystemTest, is_local) {
+  bool TestDirectoryIsLocal;
+  ASSERT_NO_ERROR(fs::is_local(TestDirectory, TestDirectoryIsLocal));
+  EXPECT_EQ(TestDirectoryIsLocal, fs::is_local(TestDirectory));
+
+  int FD;
+  SmallString<128> TempPath;
+  ASSERT_NO_ERROR(
+      fs::createUniqueFile(Twine(TestDirectory) + "/temp", FD, TempPath));
+  FileRemover Cleanup(TempPath);
+
+  // Make sure it exists.
+  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
+
+  bool TempFileIsLocal;
+  ASSERT_NO_ERROR(fs::is_local(FD, TempFileIsLocal));
+  EXPECT_EQ(TempFileIsLocal, fs::is_local(FD));
+  ::close(FD);
+
+  // Expect that the file and its parent directory are equally local or equally
+  // remote.
+  EXPECT_EQ(TestDirectoryIsLocal, TempFileIsLocal);
+}
+
+TEST_F(FileSystemTest, getUmask) {
+#ifdef _WIN32
+  EXPECT_EQ(fs::getUmask(), 0U) << "Should always be 0 on Windows.";
+#else
+  unsigned OldMask = ::umask(0022);
+  unsigned CurrentMask = fs::getUmask();
+  EXPECT_EQ(CurrentMask, 0022U)
+      << "getUmask() didn't return previously set umask()";
+  EXPECT_EQ(::umask(OldMask), 0022U) << "getUmask() may have changed umask()";
+#endif
+}
+
+TEST_F(FileSystemTest, RespectUmask) {
+#ifndef _WIN32
+  unsigned OldMask = ::umask(0022);
+
+  int FD;
+  SmallString<128> TempPath;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+
+  fs::perms AllRWE = static_cast<fs::perms>(0777);
+
+  ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE));
+
+  ErrorOr<fs::perms> Perms = fs::getPermissions(TempPath);
+  ASSERT_TRUE(!!Perms);
+  EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask by default";
+
+  ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE));
+
+  Perms = fs::getPermissions(TempPath);
+  ASSERT_TRUE(!!Perms);
+  EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask";
+
+  ASSERT_NO_ERROR(
+      fs::setPermissions(FD, static_cast<fs::perms>(AllRWE & ~fs::getUmask())));
+  Perms = fs::getPermissions(TempPath);
+  ASSERT_TRUE(!!Perms);
+  EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0755))
+      << "Did not respect umask";
+
+  (void)::umask(0057);
+
+  ASSERT_NO_ERROR(
+      fs::setPermissions(FD, static_cast<fs::perms>(AllRWE & ~fs::getUmask())));
+  Perms = fs::getPermissions(TempPath);
+  ASSERT_TRUE(!!Perms);
+  EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0720))
+      << "Did not respect umask";
+
+  (void)::umask(OldMask);
+  (void)::close(FD);
+#endif
+}
+
 TEST_F(FileSystemTest, set_current_path) {
   SmallString<128> path;
 
@@ -1665,9 +1755,10 @@
   EXPECT_TRUE(CheckPermissions(fs::set_gid_on_exe));
 
   // Modern BSDs require root to set the sticky bit on files.
-  // AIX without root will mask off (i.e., lose) the sticky bit on files.
+  // AIX and Solaris without root will mask off (i.e., lose) the sticky bit
+  // on files.
 #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) &&  \
-    !defined(_AIX)
+    !defined(_AIX) && !(defined(__sun__) && defined(__svr4__))
   EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError);
   EXPECT_TRUE(CheckPermissions(fs::sticky_bit));
 
diff --git a/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
index 85b1839..dbfaf8e 100644
--- a/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/Support/ProcessTest.cpp -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp b/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
index ec1c85a..85a1d53 100644
--- a/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/Support/ProgramTest.cpp -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/RegexTest.cpp b/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
index 7e44a3c..eb8160e 100644
--- a/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/RegexTest.cpp - Regex tests --===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp b/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
index 15143be..d2273d7 100644
--- a/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/ReplaceFileTest.cpp - unit tests -------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -53,7 +52,8 @@
 };
 
 bool FDHasContent(int FD, StringRef Content) {
-  auto Buffer = MemoryBuffer::getOpenFile(FD, "", -1);
+  auto Buffer =
+      MemoryBuffer::getOpenFile(sys::fs::convertFDToNativeFile(FD), "", -1);
   assert(Buffer);
   return Buffer.get()->getBuffer() == Content;
 }
@@ -147,8 +147,9 @@
     std::error_code EC;
     ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, TargetFD));
     ScopedFD X(TargetFD);
-    sys::fs::mapped_file_region MFR(
-        TargetFD, sys::fs::mapped_file_region::readonly, 10, 0, EC);
+    sys::fs::mapped_file_region MFR(sys::fs::convertFDToNativeFile(TargetFD),
+                                    sys::fs::mapped_file_region::readonly, 10,
+                                    0, EC);
     ASSERT_FALSE(EC);
 
     ASSERT_NO_ERROR(fs::rename(SourceFileName, TargetFileName));
diff --git a/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
index 930bd43..05804e6 100644
--- a/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/ReverseIterationTest.cpp ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===---------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp b/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
index 9e3f6de..3fa63b7 100644
--- a/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/ScaledNumberTest.cpp - ScaledPair tests -----==//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -563,4 +562,7 @@
   EXPECT_EQ(1u, (n * n).toInt<uint32_t>());
 }
 
+static_assert(is_trivially_copyable<ScaledNumber<uint32_t>>::value,
+              "trivially copyable");
+
 } // end namespace
diff --git a/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp b/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
index 7bb76f5..a3079a4 100644
--- a/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/SourceMgrTest.cpp - SourceMgr tests --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
index 060703e..2245588 100644
--- a/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -1,9 +1,8 @@
 //===- SpecialCaseListTest.cpp - Unit tests for SpecialCaseList -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/StringPool.cpp b/src/llvm-project/llvm/unittests/Support/StringPool.cpp
index ac39fec..0a540e9 100644
--- a/src/llvm-project/llvm/unittests/Support/StringPool.cpp
+++ b/src/llvm-project/llvm/unittests/Support/StringPool.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/StringPoiil.cpp - StringPool tests -----------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp b/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
index 474eac6..9581f07 100644
--- a/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/SwapByteOrderTest.cpp - swap byte order test -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp b/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
index 717df62..6db4b2a 100644
--- a/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/SymbolRemappingReaderTest.cpp --------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp b/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
index 901dd90..bd67e03 100644
--- a/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/TarWriterTest.cpp ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
index 18bbb6a..04ee379 100644
--- a/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
@@ -1,9 +1,8 @@
 //===----------- TargetParser.cpp - Target Parser -------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -28,7 +27,8 @@
     "armv8l",      "armv8.1-a",    "armv8.1a",    "armv8.2-a",    "armv8.2a",
     "armv8.3-a",   "armv8.3a",     "armv8.4-a",   "armv8.4a",     "armv8.5-a",
     "armv8.5a",     "armv8-r",     "armv8r",      "armv8-m.base", "armv8m.base",
-    "armv8-m.main", "armv8m.main", "iwmmxt",      "iwmmxt2",      "xscale"
+    "armv8-m.main", "armv8m.main", "iwmmxt",      "iwmmxt2",      "xscale",
+    "armv8.1-m.main",
 };
 
 bool testARMCPU(StringRef CPUName, StringRef ExpectedArch,
@@ -245,6 +245,18 @@
                          ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
                          ARM::AEK_RAS | ARM::AEK_DOTPROD,
                          "8.2-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+                         ARM::AEK_RAS | ARM::AEK_DOTPROD,
+                         "8.2-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+                         ARM::AEK_RAS | ARM::AEK_DOTPROD,
+                         "8.2-A"));
   EXPECT_TRUE(testARMCPU("cyclone", "armv8-a", "crypto-neon-fp-armv8",
                          ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
@@ -271,10 +283,18 @@
                          ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_DOTPROD |
                          ARM::AEK_FP16 | ARM::AEK_RAS,
                          "8.2-A"));
+  EXPECT_TRUE(testARMCPU("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_DOTPROD |
+                         ARM::AEK_FP16 | ARM::AEK_RAS,
+                         "8.2-A"));
   EXPECT_TRUE(testARMCPU("cortex-m23", "armv8-m.base", "none",
                          ARM::AEK_HWDIVTHUMB, "8-M.Baseline"));
   EXPECT_TRUE(testARMCPU("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
                          ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"));
+  EXPECT_TRUE(testARMCPU("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"));
   EXPECT_TRUE(testARMCPU("iwmmxt", "iwmmxt", "none",
                          ARM::AEK_NONE, "iwmmxt"));
   EXPECT_TRUE(testARMCPU("xscale", "xscale", "none",
@@ -284,7 +304,7 @@
                          "7-S"));
 }
 
-static constexpr unsigned NumARMCPUArchs = 82;
+static constexpr unsigned NumARMCPUArchs = 86;
 
 TEST(TargetParserTest, testARMCPUArchList) {
   SmallVector<StringRef, NumARMCPUArchs> List;
@@ -399,6 +419,9 @@
       testARMArch("armv8-m.main", "generic", "v8m.main",
                           ARMBuildAttrs::CPUArch::v8_M_Main));
   EXPECT_TRUE(
+      testARMArch("armv8.1-m.main", "generic", "v8.1m.main",
+                          ARMBuildAttrs::CPUArch::v8_1_M_Main));
+  EXPECT_TRUE(
       testARMArch("iwmmxt", "iwmmxt", "",
                           ARMBuildAttrs::CPUArch::v5TE));
   EXPECT_TRUE(
@@ -546,15 +569,37 @@
 }
 
 TEST(TargetParserTest, ARMExtensionFeatures) {
-  std::vector<StringRef> Features;
-  unsigned Extensions = ARM::AEK_CRC | ARM::AEK_CRYPTO | ARM::AEK_DSP |
-                        ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_MP |
-                        ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_RAS | ARM::AEK_FP16 |
-                        ARM::AEK_FP16FML;
+  std::map<unsigned, std::vector<StringRef>> Extensions;
 
-  for (unsigned i = 0; i <= Extensions; i++)
-    EXPECT_TRUE(i == 0 ? !ARM::getExtensionFeatures(i, Features)
-                       : ARM::getExtensionFeatures(i, Features));
+  for (auto &Ext : ARM::ARCHExtNames) {
+    if (Ext.Feature && Ext.NegFeature)
+      Extensions[Ext.ID] = { StringRef(Ext.Feature),
+                             StringRef(Ext.NegFeature) };
+  }
+
+  Extensions[ARM::AEK_HWDIVARM]   = { "+hwdiv-arm", "-hwdiv-arm" };
+  Extensions[ARM::AEK_HWDIVTHUMB] = { "+hwdiv",     "-hwdiv" };
+
+  std::vector<StringRef> Features;
+
+  EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features));
+
+  for (auto &E : Extensions) {
+    // test +extension
+    Features.clear();
+    ARM::getExtensionFeatures(E.first, Features);
+    auto Found =
+        std::find(std::begin(Features), std::end(Features), E.second.at(0));
+    EXPECT_TRUE(Found != std::end(Features));
+    EXPECT_TRUE(Extensions.size() == Features.size());
+
+    // test -extension
+    Features.clear();
+    ARM::getExtensionFeatures(~E.first, Features);
+    Found = std::find(std::begin(Features), std::end(Features), E.second.at(1));
+    EXPECT_TRUE(Found != std::end(Features));
+    EXPECT_TRUE(Extensions.size() == Features.size());
+  }
 }
 
 TEST(TargetParserTest, ARMFPUFeatures) {
@@ -586,7 +631,9 @@
                               {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
                               {"maverick", "maverick", nullptr, nullptr},
                               {"xscale", "noxscale", nullptr, nullptr},
-                              {"sb", "nosb", "+sb", "-sb"}};
+                              {"sb", "nosb", "+sb", "-sb"},
+                              {"mve", "nomve", "+mve", "-mve"},
+                              {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}};
 
   for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
     EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0]));
@@ -609,7 +656,7 @@
       "v7",   "v7a",    "v7ve",  "v7hl",   "v7l",   "v7-r",   "v7r",   "v7-m",
       "v7m",  "v7k",    "v7s",   "v7e-m",  "v7em",  "v8-a",   "v8",    "v8a",
       "v8l",  "v8.1-a", "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a",
-      "v8.4a", "v8.5-a","v8.5a", "v8-r"
+      "v8.4a", "v8.5-a","v8.5a", "v8-r",   "v8m.base", "v8m.main", "v8.1m.main"
   };
 
   for (unsigned i = 0; i < array_lengthof(Arch); i++) {
@@ -639,12 +686,15 @@
   }
 
   EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64"));
+  EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("arm64_32"));
   EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be"));
 
   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64"));
   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be"));
   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64"));
   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be"));
+  EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_32"));
+  EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_32"));
 }
 
 TEST(TargetParserTest, ARMparseArchProfile) {
@@ -655,6 +705,7 @@
     case ARM::ArchKind::ARMV7EM:
     case ARM::ArchKind::ARMV8MMainline:
     case ARM::ArchKind::ARMV8MBaseline:
+    case ARM::ArchKind::ARMV8_1MMainline:
       EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i]));
       break;
     case ARM::ArchKind::ARMV7R:
@@ -745,6 +796,18 @@
       AArch64::AEK_RDM | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
       AArch64::AEK_RCPC, "8.2-A"));
   EXPECT_TRUE(testAArch64CPU(
+      "cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_RDM | AArch64::AEK_SIMD | AArch64::AEK_RAS |
+      AArch64::AEK_LSE | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+      AArch64::AEK_RCPC| AArch64::AEK_SSBS, "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_RDM | AArch64::AEK_SIMD | AArch64::AEK_RAS |
+      AArch64::AEK_LSE | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+      AArch64::AEK_RCPC| AArch64::AEK_SSBS, "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
       "cyclone", "armv8-a", "crypto-neon-fp-armv8",
       AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, "8-A"));
   EXPECT_TRUE(testAArch64CPU(
@@ -766,6 +829,12 @@
       AArch64::AEK_LSE | AArch64::AEK_RAS | AArch64::AEK_RDM |
       AArch64::AEK_SIMD, "8.2-A"));
   EXPECT_TRUE(testAArch64CPU(
+      "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
+      AArch64::AEK_DOTPROD | AArch64::AEK_FP | AArch64::AEK_FP16 |
+      AArch64::AEK_LSE | AArch64::AEK_RAS | AArch64::AEK_RDM |
+      AArch64::AEK_SIMD, "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
       "falkor", "armv8-a", "crypto-neon-fp-armv8",
       AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
       AArch64::AEK_SIMD | AArch64::AEK_RDM, "8-A"));
@@ -806,7 +875,7 @@
       "8.2-A"));
 }
 
-static constexpr unsigned NumAArch64CPUArchs = 21;
+static constexpr unsigned NumAArch64CPUArchs = 24;
 
 TEST(TargetParserTest, testAArch64CPUArchList) {
   SmallVector<StringRef, NumAArch64CPUArchs> List;
@@ -874,15 +943,25 @@
   EXPECT_FALSE(testAArch64Extension("exynos-m3",
                                     AArch64::ArchKind::INVALID, "ras"));
   EXPECT_TRUE(testAArch64Extension("exynos-m4",
+                                   AArch64::ArchKind::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4",
+                                   AArch64::ArchKind::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4",
                                    AArch64::ArchKind::INVALID, "lse"));
   EXPECT_TRUE(testAArch64Extension("exynos-m4",
-                                   AArch64::ArchKind::INVALID, "rdm"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m4",
                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_FALSE(testAArch64Extension("exynos-m4",
-                                    AArch64::ArchKind::INVALID, "fullfp16"));
   EXPECT_TRUE(testAArch64Extension("exynos-m4",
+                                   AArch64::ArchKind::INVALID, "rdm"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5",
                                    AArch64::ArchKind::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5",
+                                   AArch64::ArchKind::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5",
+                                   AArch64::ArchKind::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5",
+                                   AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5",
+                                   AArch64::ArchKind::INVALID, "rdm"));
   EXPECT_TRUE(testAArch64Extension("falkor",
                                    AArch64::ArchKind::INVALID, "rdm"));
   EXPECT_FALSE(testAArch64Extension("kryo",
@@ -961,18 +1040,50 @@
 }
 
 TEST(TargetParserTest, AArch64ExtensionFeatures) {
-  std::vector<StringRef> Features;
-  unsigned Extensions = AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
-                        AArch64::AEK_FP | AArch64::AEK_SIMD |
-                        AArch64::AEK_FP16 | AArch64::AEK_PROFILE |
-                        AArch64::AEK_RAS | AArch64::AEK_LSE |
-                        AArch64::AEK_RDM | AArch64::AEK_SVE |
-                        AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
-                        AArch64::AEK_FP16FML;
+  std::vector<unsigned> Extensions = {
+    AArch64::AEK_CRC,      AArch64::AEK_CRYPTO,
+    AArch64::AEK_FP,       AArch64::AEK_SIMD,
+    AArch64::AEK_FP16,     AArch64::AEK_PROFILE,
+    AArch64::AEK_RAS,      AArch64::AEK_LSE,
+    AArch64::AEK_RDM,      AArch64::AEK_DOTPROD,
+    AArch64::AEK_SVE,      AArch64::AEK_SVE2,
+    AArch64::AEK_SVE2AES,  AArch64::AEK_SVE2SM4,
+    AArch64::AEK_SVE2SHA3, AArch64::AEK_SVE2BITPERM,
+    AArch64::AEK_RCPC,     AArch64::AEK_FP16FML };
 
-  for (unsigned i = 0; i <= Extensions; i++)
-    EXPECT_TRUE(i == 0 ? !AArch64::getExtensionFeatures(i, Features)
-                       : AArch64::getExtensionFeatures(i, Features));
+  std::vector<StringRef> Features;
+
+  unsigned ExtVal = 0;
+  for (auto Ext : Extensions)
+    ExtVal |= Ext;
+
+  EXPECT_FALSE(AArch64::getExtensionFeatures(AArch64::AEK_INVALID, Features));
+  EXPECT_TRUE(!Features.size());
+
+  AArch64::getExtensionFeatures(ExtVal, Features);
+  EXPECT_TRUE(Extensions.size() == Features.size());
+
+  auto B = std::begin(Features);
+  auto E = std::end(Features);
+
+  EXPECT_TRUE(std::find(B, E, "+crc") != E);
+  EXPECT_TRUE(std::find(B, E, "+crypto") != E);
+  EXPECT_TRUE(std::find(B, E, "+fp-armv8") != E);
+  EXPECT_TRUE(std::find(B, E, "+neon") != E);
+  EXPECT_TRUE(std::find(B, E, "+fullfp16") != E);
+  EXPECT_TRUE(std::find(B, E, "+spe") != E);
+  EXPECT_TRUE(std::find(B, E, "+ras") != E);
+  EXPECT_TRUE(std::find(B, E, "+lse") != E);
+  EXPECT_TRUE(std::find(B, E, "+rdm") != E);
+  EXPECT_TRUE(std::find(B, E, "+dotprod") != E);
+  EXPECT_TRUE(std::find(B, E, "+rcpc") != E);
+  EXPECT_TRUE(std::find(B, E, "+fp16fml") != E);
+  EXPECT_TRUE(std::find(B, E, "+sve") != E);
+  EXPECT_TRUE(std::find(B, E, "+sve2") != E);
+  EXPECT_TRUE(std::find(B, E, "+sve2-aes") != E);
+  EXPECT_TRUE(std::find(B, E, "+sve2-sm4") != E);
+  EXPECT_TRUE(std::find(B, E, "+sve2-sha3") != E);
+  EXPECT_TRUE(std::find(B, E, "+sve2-bitperm") != E);
 }
 
 TEST(TargetParserTest, AArch64ArchFeatures) {
@@ -996,6 +1107,15 @@
                               {"lse", "nolse", "+lse", "-lse"},
                               {"rdm", "nordm", "+rdm", "-rdm"},
                               {"sve", "nosve", "+sve", "-sve"},
+                              {"sve2", "nosve2", "+sve2", "-sve2"},
+                              {"sve2-aes", "nosve2-aes", "+sve2-aes",
+                               "-sve2-aes"},
+                              {"sve2-sm4", "nosve2-sm4", "+sve2-sm4",
+                               "-sve2-sm4"},
+                              {"sve2-sha3", "nosve2-sha3", "+sve2-sha3",
+                               "-sve2-sha3"},
+                              {"sve2-bitperm", "nosve2-bitperm",
+                               "+sve2-bitperm", "-sve2-bitperm"},
                               {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
                               {"rcpc", "norcpc", "+rcpc", "-rcpc" },
                               {"rng", "norng", "+rand", "-rand"},
diff --git a/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp b/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
index 14ca9c0..0a8aeca 100644
--- a/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
@@ -1,9 +1,8 @@
 //========- unittests/Support/TaskQueue.cpp - TaskQueue.h tests ------========//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp b/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
index e71c7db..075d7d9 100644
--- a/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/ThreadLocalTest.cpp - ThreadLocal tests ------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
index 0da33ad..4755b52 100644
--- a/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
@@ -1,9 +1,8 @@
 //========- unittests/Support/ThreadPools.cpp - ThreadPools.h tests --========//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/Threading.cpp b/src/llvm-project/llvm/unittests/Support/Threading.cpp
index be53026..01f1c51 100644
--- a/src/llvm-project/llvm/unittests/Support/Threading.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Threading.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Threading.cpp - Thread tests -----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/TimerTest.cpp b/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
index a92ecf1..9a9b67e 100644
--- a/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/TimerTest.cpp - Timer tests ------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
index 23acc54..967f6f6 100644
--- a/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
@@ -1,9 +1,8 @@
 //=== - llvm/unittest/Support/TrailingObjectsTest.cpp ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
index df42c1e..9b10daa 100644
--- a/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
@@ -1,9 +1,8 @@
 //===- TrigramIndexTest.cpp - Unit tests for TrigramIndex -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp b/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
index 63381d4..c896293 100644
--- a/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
@@ -1,9 +1,8 @@
 //===- TypeNameTest.cpp ---------------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp b/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
index 7a3ce53..e7a1025 100644
--- a/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
@@ -1,13 +1,13 @@
 //===- TypeTraitsTest.cpp -------------------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/type_traits.h"
+#include "gtest/gtest.h"
 
 namespace {
 
@@ -72,6 +72,26 @@
 template void TrivialityTester<A &&, false, true>();
 template void TrivialityTester<B &&, false, true>();
 
+TEST(Triviality, Tester) {
+  TrivialityTester<int, true, true>();
+  TrivialityTester<void *, true, true>();
+  TrivialityTester<int &, true, true>();
+  TrivialityTester<int &&, false, true>();
+
+  TrivialityTester<X, true, true>();
+  TrivialityTester<Y, false, false>();
+  TrivialityTester<Z, false, false>();
+  TrivialityTester<A, true, false>();
+  TrivialityTester<B, false, true>();
+
+  TrivialityTester<Z &, true, true>();
+  TrivialityTester<A &, true, true>();
+  TrivialityTester<B &, true, true>();
+  TrivialityTester<Z &&, false, true>();
+  TrivialityTester<A &&, false, true>();
+  TrivialityTester<B &&, false, true>();
+}
+
 } // namespace triviality
 
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp b/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
index 0733397..376fbee 100644
--- a/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/UnicodeTest.cpp - Unicode.h tests ----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp b/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
index cd7ecda..af6c0a7 100644
--- a/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
@@ -1,9 +1,8 @@
 //===- VersionTupleTests.cpp - Version Number Handling Tests --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
index 7b42943..a867bc5 100644
--- a/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -1,9 +1,8 @@
 //===- unittests/Support/VirtualFileSystem.cpp -------------- VFS tests ---===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -343,6 +342,57 @@
   EXPECT_EQ(0200, Status->getPermissions());
 }
 
+TEST(VirtualFileSystemTest, OverlayIterator) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("/foo");
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  ErrorOr<vfs::Status> Status((std::error_code()));
+  {
+    auto it = O->overlays_begin();
+    auto end = O->overlays_end();
+
+    EXPECT_NE(it, end);
+
+    Status = (*it)->status("/foo");
+    ASSERT_TRUE(Status.getError());
+
+    it++;
+    EXPECT_NE(it, end);
+
+    Status = (*it)->status("/foo");
+    ASSERT_FALSE(Status.getError());
+    EXPECT_TRUE(Status->exists());
+
+    it++;
+    EXPECT_EQ(it, end);
+  }
+
+  {
+    auto it = O->overlays_rbegin();
+    auto end = O->overlays_rend();
+
+    EXPECT_NE(it, end);
+
+    Status = (*it)->status("/foo");
+    ASSERT_FALSE(Status.getError());
+    EXPECT_TRUE(Status->exists());
+
+    it++;
+    EXPECT_NE(it, end);
+
+    Status = (*it)->status("/foo");
+    ASSERT_TRUE(Status.getError());
+
+    it++;
+    EXPECT_EQ(it, end);
+  }
+}
+
 namespace {
 struct ScopedDir {
   SmallString<128> Path;
@@ -350,13 +400,18 @@
     std::error_code EC;
     if (Unique) {
       EC = llvm::sys::fs::createUniqueDirectory(Name, Path);
+      if (!EC) {
+        // Resolve any symlinks in the new directory.
+        std::string UnresolvedPath = Path.str();
+        EC = llvm::sys::fs::real_path(UnresolvedPath, Path);
+      }
     } else {
       Path = Name.str();
       EC = llvm::sys::fs::create_directory(Twine(Path));
     }
     if (EC)
       Path = "";
-    EXPECT_FALSE(EC);
+    EXPECT_FALSE(EC) << EC.message();
   }
   ~ScopedDir() {
     if (Path != "") {
@@ -382,6 +437,26 @@
   }
   operator StringRef() { return Path.str(); }
 };
+
+struct ScopedFile {
+  SmallString<128> Path;
+  ScopedFile(const Twine &Path, StringRef Contents) {
+    Path.toVector(this->Path);
+    std::error_code EC;
+    raw_fd_ostream OS(this->Path, EC);
+    EXPECT_FALSE(EC);
+    OS << Contents;
+    OS.flush();
+    EXPECT_FALSE(OS.error());
+    if (EC || OS.error())
+      this->Path = "";
+  }
+  ~ScopedFile() {
+    if (Path != "") {
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+    }
+  }
+};
 } // end anonymous namespace
 
 TEST(VirtualFileSystemTest, BasicRealFSIteration) {
@@ -412,6 +487,67 @@
 }
 
 #ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, MultipleWorkingDirs) {
+  // Our root contains a/aa, b/bb, c, where c is a link to a/.
+  // Run tests both in root/b/ and root/c/ (to test "normal" and symlink dirs).
+  // Interleave operations to show the working directories are independent.
+  ScopedDir Root("r", true), ADir(Root.Path + "/a"), BDir(Root.Path + "/b");
+  ScopedLink C(ADir.Path, Root.Path + "/c");
+  ScopedFile AA(ADir.Path + "/aa", "aaaa"), BB(BDir.Path + "/bb", "bbbb");
+  std::unique_ptr<vfs::FileSystem> BFS = vfs::createPhysicalFileSystem(),
+                                   CFS = vfs::createPhysicalFileSystem();
+
+  ASSERT_FALSE(BFS->setCurrentWorkingDirectory(BDir.Path));
+  ASSERT_FALSE(CFS->setCurrentWorkingDirectory(C.Path));
+  EXPECT_EQ(BDir.Path, *BFS->getCurrentWorkingDirectory());
+  EXPECT_EQ(C.Path, *CFS->getCurrentWorkingDirectory());
+
+  // openFileForRead(), indirectly.
+  auto BBuf = BFS->getBufferForFile("bb");
+  ASSERT_TRUE(BBuf);
+  EXPECT_EQ("bbbb", (*BBuf)->getBuffer());
+
+  auto ABuf = CFS->getBufferForFile("aa");
+  ASSERT_TRUE(ABuf);
+  EXPECT_EQ("aaaa", (*ABuf)->getBuffer());
+
+  // status()
+  auto BStat = BFS->status("bb");
+  ASSERT_TRUE(BStat);
+  EXPECT_EQ("bb", BStat->getName());
+
+  auto AStat = CFS->status("aa");
+  ASSERT_TRUE(AStat);
+  EXPECT_EQ("aa", AStat->getName()); // unresolved name
+
+  // getRealPath()
+  SmallString<128> BPath;
+  ASSERT_FALSE(BFS->getRealPath("bb", BPath));
+  EXPECT_EQ(BB.Path, BPath);
+
+  SmallString<128> APath;
+  ASSERT_FALSE(CFS->getRealPath("aa", APath));
+  EXPECT_EQ(AA.Path, APath); // Reports resolved name.
+
+  // dir_begin
+  std::error_code EC;
+  auto BIt = BFS->dir_begin(".", EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(BIt, vfs::directory_iterator());
+  EXPECT_EQ((BDir.Path + "/./bb").str(), BIt->path());
+  BIt.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_EQ(BIt, vfs::directory_iterator());
+
+  auto CIt = CFS->dir_begin(".", EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(CIt, vfs::directory_iterator());
+  EXPECT_EQ((ADir.Path + "/./aa").str(), CIt->path()); // Partly resolved name!
+  CIt.increment(EC); // Because likely to read through this path.
+  ASSERT_FALSE(EC);
+  ASSERT_EQ(CIt, vfs::directory_iterator());
+}
+
 TEST(VirtualFileSystemTest, BrokenSymlinkRealFSIteration) {
   ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
   IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
@@ -777,7 +913,7 @@
 
   bool Local = true;
   ASSERT_FALSE(PFS.isLocal("/a", Local));
-  ASSERT_EQ(false, Local);
+  EXPECT_FALSE(Local);
 }
 
 class InMemoryFileSystemTest : public ::testing::Test {
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
index 17f38f9..e02f68f 100644
--- a/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
@@ -1,12 +1,12 @@
 //===- unittest/Support/YAMLIOTest.cpp ------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
@@ -580,6 +580,90 @@
   }
 }
 
+enum class Enum : uint16_t { One, Two };
+enum class BitsetEnum : uint16_t {
+  ZeroOne = 0x01,
+  OneZero = 0x10,
+  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ OneZero),
+};
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+struct EndianEnums {
+  llvm::support::little_t<Enum> LittleEnum;
+  llvm::support::big_t<Enum> BigEnum;
+  llvm::support::little_t<BitsetEnum> LittleBitset;
+  llvm::support::big_t<BitsetEnum> BigBitset;
+};
+namespace llvm {
+namespace yaml {
+template <> struct ScalarEnumerationTraits<Enum> {
+  static void enumeration(IO &io, Enum &E) {
+    io.enumCase(E, "One", Enum::One);
+    io.enumCase(E, "Two", Enum::Two);
+  }
+};
+
+template <> struct ScalarBitSetTraits<BitsetEnum> {
+  static void bitset(IO &io, BitsetEnum &E) {
+    io.bitSetCase(E, "ZeroOne", BitsetEnum::ZeroOne);
+    io.bitSetCase(E, "OneZero", BitsetEnum::OneZero);
+  }
+};
+
+template <> struct MappingTraits<EndianEnums> {
+  static void mapping(IO &io, EndianEnums &EE) {
+    io.mapRequired("LittleEnum", EE.LittleEnum);
+    io.mapRequired("BigEnum", EE.BigEnum);
+    io.mapRequired("LittleBitset", EE.LittleBitset);
+    io.mapRequired("BigBitset", EE.BigBitset);
+  }
+};
+} // namespace yaml
+} // namespace llvm
+
+TEST(YAMLIO, TestReadEndianEnums) {
+  EndianEnums map;
+  Input yin("---\n"
+            "LittleEnum:   One\n"
+            "BigEnum:      Two\n"
+            "LittleBitset: [ ZeroOne ]\n"
+            "BigBitset:    [ ZeroOne, OneZero ]\n"
+            "...\n");
+  yin >> map;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(Enum::One, map.LittleEnum);
+  EXPECT_EQ(Enum::Two, map.BigEnum);
+  EXPECT_EQ(BitsetEnum::ZeroOne, map.LittleBitset);
+  EXPECT_EQ(BitsetEnum::ZeroOne | BitsetEnum::OneZero, map.BigBitset);
+}
+
+TEST(YAMLIO, TestReadWriteEndianEnums) {
+  std::string intermediate;
+  {
+    EndianEnums map;
+    map.LittleEnum = Enum::Two;
+    map.BigEnum = Enum::One;
+    map.LittleBitset = BitsetEnum::OneZero | BitsetEnum::ZeroOne;
+    map.BigBitset = BitsetEnum::OneZero;
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << map;
+  }
+
+  {
+    Input yin(intermediate);
+    EndianEnums map;
+    yin >> map;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(Enum::Two, map.LittleEnum);
+    EXPECT_EQ(Enum::One, map.BigEnum);
+    EXPECT_EQ(BitsetEnum::OneZero | BitsetEnum::ZeroOne, map.LittleBitset);
+    EXPECT_EQ(BitsetEnum::OneZero, map.BigBitset);
+  }
+}
+
 struct StringTypes {
   llvm::StringRef str1;
   llvm::StringRef str2;
@@ -604,6 +688,7 @@
   std::string stdstr10;
   std::string stdstr11;
   std::string stdstr12;
+  std::string stdstr13;
 };
 
 namespace llvm {
@@ -634,6 +719,7 @@
       io.mapRequired("stdstr10",  st.stdstr10);
       io.mapRequired("stdstr11",  st.stdstr11);
       io.mapRequired("stdstr12",  st.stdstr12);
+      io.mapRequired("stdstr13",  st.stdstr13);
     }
   };
 }
@@ -666,6 +752,7 @@
     map.stdstr10 = "0.2e20";
     map.stdstr11 = "0x30";
     map.stdstr12 = "- match";
+    map.stdstr13.assign("\0a\0b\0", 5);
 
     llvm::raw_string_ostream ostr(intermediate);
     Output yout(ostr);
@@ -691,6 +778,7 @@
   EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
   EXPECT_NE(std::string::npos, flowOut.find("''\n"));
   EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
+  EXPECT_NE(std::string::npos, flowOut.find("\"\\0a\\0b\\0\""));
 
   {
     Input yin(intermediate);
@@ -710,6 +798,7 @@
     EXPECT_TRUE(map.stdstr4 == "@hhh");
     EXPECT_TRUE(map.stdstr5 == "");
     EXPECT_TRUE(map.stdstr6 == "0000000004000000");
+    EXPECT_EQ(std::string("\0a\0b\0", 5), map.stdstr13);
   }
 }
 
@@ -824,7 +913,7 @@
       io.mapRequired("f1", c.f1);
       io.mapRequired("f2", c.f2);
       io.mapRequired("f3", c.f3);
-      io.mapOptional("f4", c.f4, MyFlags(flagRound));
+      io.mapOptional("f4", c.f4, flagRound);
      }
   };
 }
@@ -1328,8 +1417,8 @@
     static void mapping(IO &io, TotalSeconds &secs) {
       MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs);
 
-      io.mapOptional("hours",    keys->hours,    (uint32_t)0);
-      io.mapOptional("minutes",  keys->minutes,  (uint8_t)0);
+      io.mapOptional("hours", keys->hours, 0);
+      io.mapOptional("minutes", keys->minutes, 0);
       io.mapRequired("seconds",  keys->seconds);
     }
   };
@@ -2439,7 +2528,7 @@
   ostr.flush();
   EXPECT_EQ(1, Context.A);
   EXPECT_EQ("---\n"
-            "Simple:          \n"
+            "Simple:\n"
             "  B:               0\n"
             "  C:               0\n"
             "  Context:         1\n"
@@ -2454,7 +2543,7 @@
   ostr.flush();
   EXPECT_EQ(2, Context.A);
   EXPECT_EQ("---\n"
-            "Simple:          \n"
+            "Simple:\n"
             "  B:               2\n"
             "  C:               3\n"
             "  Context:         2\n"
@@ -2467,8 +2556,6 @@
 
 TEST(YAMLIO, TestCustomMapping) {
   std::map<std::string, int> x;
-  x["foo"] = 1;
-  x["bar"] = 2;
 
   std::string out;
   llvm::raw_string_ostream ostr(out);
@@ -2477,6 +2564,17 @@
   xout << x;
   ostr.flush();
   EXPECT_EQ("---\n"
+            "{}\n"
+            "...\n",
+            out);
+
+  x["foo"] = 1;
+  x["bar"] = 2;
+
+  out.clear();
+  xout << x;
+  ostr.flush();
+  EXPECT_EQ("---\n"
             "bar:             2\n"
             "foo:             1\n"
             "...\n",
@@ -2506,10 +2604,10 @@
   xout << x;
   ostr.flush();
   EXPECT_EQ("---\n"
-            "bar:             \n"
+            "bar:\n"
             "  foo:             3\n"
             "  bar:             4\n"
-            "foo:             \n"
+            "foo:\n"
             "  foo:             1\n"
             "  bar:             2\n"
             "...\n",
@@ -2525,6 +2623,38 @@
   EXPECT_EQ(4, y["bar"].bar);
 }
 
+struct FooBarMapMap {
+  std::map<std::string, FooBar> fbm;
+};
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<FooBarMapMap> {
+  static void mapping(IO &io, FooBarMapMap &x) {
+    io.mapRequired("fbm", x.fbm);
+  }
+};
+}
+}
+
+TEST(YAMLIO, TestEmptyMapWrite) {
+  FooBarMapMap cont;
+  std::string str;
+  llvm::raw_string_ostream OS(str);
+  Output yout(OS);
+  yout << cont;
+  EXPECT_EQ(OS.str(), "---\nfbm:             {}\n...\n");
+}
+
+TEST(YAMLIO, TestEmptySequenceWrite) {
+  FooBarContainer cont;
+  std::string str;
+  llvm::raw_string_ostream OS(str);
+  Output yout(OS);
+  yout << cont;
+  EXPECT_EQ(OS.str(), "---\nfbs:             []\n...\n");
+}
+
 static void TestEscaped(llvm::StringRef Input, llvm::StringRef Expected) {
   std::string out;
   llvm::raw_string_ostream ostr(out);
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
index 7962f3c..06d4b0e 100644
--- a/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
@@ -1,9 +1,8 @@
 //===- unittest/Support/YAMLParserTest ------------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
index 2b8f065..0fe0869 100644
--- a/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/formatted_raw_ostream_test.cpp ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
index a75f446..4ce4917 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream tests -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
index a528fd2..459eb940 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
@@ -1,9 +1,8 @@
 //===- raw_pwrite_stream_test.cpp - raw_pwrite_stream tests ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
index e176f3f..be03536 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream tests -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp b/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
index 6a88a2d..7dc7c40 100644
--- a/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Support/xxhashTest.cpp -------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp b/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
index 095ee06..49a469b 100644
--- a/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
@@ -1,9 +1,8 @@
 //=== WebAssemblyExceptionInfoTest.cpp - WebAssebmlyExceptionInfo unit tests =//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -75,7 +74,7 @@
 
   declare i32 @__gxx_wasm_personality_v0(...)
 
-  define hidden void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+  define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
     unreachable
   }
 
@@ -101,14 +100,14 @@
   ; predecessors: %bb.0
     successors: %bb.3, %bb.9
     liveins: $value_stack
-    CATCH_ALL implicit-def $arguments
+    %0:exnref = CATCH implicit-def $arguments
     CLEANUPRET implicit-def dead $arguments
 
   bb.3 (landing-pad):
   ; predecessors: %bb.2
     successors: %bb.4, %bb.6
     liveins: $value_stack
-    CATCH_ALL implicit-def $arguments
+    %1:exnref = CATCH implicit-def $arguments
     BR_IF %bb.4, %58:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
     BR %bb.6, implicit-def $arguments
 
@@ -139,13 +138,13 @@
   ; predecessors: %bb.4
     successors: %bb.9
     liveins: $value_stack
-    CATCH_ALL implicit-def $arguments
+    %2:exnref = CATCH implicit-def $arguments
     CLEANUPRET implicit-def dead $arguments
 
   bb.9 (landing-pad):
   ; predecessors: %bb.2, %bb.6, %bb.8
     liveins: $value_stack
-    CATCH_ALL implicit-def $arguments
+    %3:exnref = CATCH implicit-def $arguments
     CLEANUPRET implicit-def dead $arguments
 
   bb.10:
@@ -238,7 +237,7 @@
 
   declare i32 @__gxx_wasm_personality_v0(...)
 
-  define hidden void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+  define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
     unreachable
   }
 
@@ -258,7 +257,7 @@
   ; predecessors: %bb.0
     successors: %bb.2, %bb.8
     liveins: $value_stack
-    %52:i32 = CATCH_I32 0, implicit-def dead $arguments
+    %0:exnref = CATCH implicit-def $arguments
     BR_IF %bb.2, %32:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
     BR %bb.8, implicit-def $arguments
 
@@ -272,7 +271,7 @@
   ; predecessors: %bb.2
     successors: %bb.4, %bb.6
     liveins: $value_stack
-    CATCH_ALL implicit-def $arguments
+    %1:exnref = CATCH implicit-def $arguments
     BR_IF %bb.4, %43:i32, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
     BR %bb.6, implicit-def $arguments
 
@@ -314,13 +313,13 @@
   ; predecessors: %bb.4
     successors: %bb.11
     liveins: $value_stack
-    CATCH_ALL implicit-def $arguments
+    %2:exnref = CATCH implicit-def $arguments
     CLEANUPRET implicit-def dead $arguments
 
   bb.11 (landing-pad):
   ; predecessors: %bb.2, %bb.6, %bb.10
     liveins: $value_stack
-    CATCH_ALL implicit-def $arguments
+    %3:exnref = CATCH implicit-def $arguments
     CLEANUPRET implicit-def dead $arguments
 
   bb.12:
@@ -416,135 +415,3 @@
   EXPECT_EQ(WE0_1->getParentException(), WE0);
   EXPECT_EQ(WE0_1->getExceptionDepth(), (unsigned)2);
 }
-
-// Terminate pad test
-TEST(WebAssemblyExceptionInfoTest, TEST2) {
-  std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
-  ASSERT_TRUE(TM);
-
-  StringRef MIRString = R"MIR(
---- |
-  target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
-  target triple = "wasm32-unknown-unknown"
-
-  declare i32 @__gxx_wasm_personality_v0(...)
-  declare void @_ZSt9terminatev()
-  declare void @__clang_call_terminate(i8*)
-
-  define hidden void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
-    unreachable
-  }
-
-...
----
-name: test2
-liveins:
-  - { reg: '$arguments' }
-  - { reg: '$value_stack' }
-body: |
-  bb.0:
-    successors: %bb.3, %bb.1
-    BR %bb.3, implicit-def dead $arguments
-
-  bb.1 (landing-pad):
-  ; predecessors: %bb.0
-    successors: %bb.2, %bb.4
-    %3:i32 = CATCH_I32 0, implicit-def dead $arguments
-    BR %bb.2, implicit-def dead $arguments
-
-  bb.2:
-  ; predecessors: %bb.1
-    successors: %bb.3(0x80000000); %bb.3(200.00%)
-    CATCHRET %bb.3, %bb.0, implicit-def dead $arguments
-
-  bb.3:
-  ; predecessors: %bb.0, %bb.2
-    RETURN_VOID implicit-def $arguments
-
-  bb.4 (landing-pad):
-  ; predecessors: %bb.1
-    successors: %bb.5, %bb.6
-    CATCH_ALL implicit-def $arguments
-    BR %bb.5, implicit-def dead $arguments
-
-  bb.5:
-  ; predecessors: %bb.4
-    CLEANUPRET implicit-def dead $arguments
-
-  bb.6 (landing-pad):
-  ; predecessors: %bb.4
-    successors: %bb.7(0x80000000); %bb.7(200.00%)
-    %6:i32 = CATCH_I32 0, implicit-def dead $arguments
-    CALL_VOID @__clang_call_terminate, %7:i32, implicit-def $arguments
-    UNREACHABLE implicit-def $arguments
-
-  bb.7 (landing-pad):
-  ; predecessors: %bb.6
-    CATCH_ALL implicit-def $arguments
-    CALL_VOID @_ZSt9terminatev, implicit-def $arguments
-    UNREACHABLE implicit-def $arguments
-)MIR";
-
-  LLVMContext Context;
-  std::unique_ptr<MIRParser> MIR;
-  MachineModuleInfo MMI(TM.get());
-  std::unique_ptr<Module> M =
-      parseMIR(Context, MIR, *TM, MIRString, "test2", MMI);
-  ASSERT_TRUE(M);
-
-  Function *F = M->getFunction("test2");
-  auto *MF = MMI.getMachineFunction(*F);
-  ASSERT_TRUE(MF);
-
-  WebAssemblyExceptionInfo WEI;
-  MachineDominatorTree MDT;
-  MachineDominanceFrontier MDF;
-  MDT.runOnMachineFunction(*MF);
-  MDF.getBase().analyze(MDT.getBase());
-  WEI.recalculate(MDT, MDF);
-
-  // Exception info structure:
-  // |- bb1 (ehpad), bb2, bb4, bb5, bb6, bb7
-  //   |- bb4 (ehpad), bb5, bb6, bb7
-  //     |- bb6 (ehpad), bb7
-  //
-  // Here, bb6 is a terminate pad with a 'catch' instruction, and bb7 is a
-  // terminate pad with a 'catch_all' instruction, In this case we put bb6 and
-  // bb7 into one exception.
-
-  auto *MBB1 = MF->getBlockNumbered(1);
-  auto *WE0 = WEI.getExceptionFor(MBB1);
-  ASSERT_TRUE(WE0);
-  EXPECT_EQ(WE0->getEHPad(), MBB1);
-  EXPECT_EQ(WE0->getParentException(), nullptr);
-  EXPECT_EQ(WE0->getExceptionDepth(), (unsigned)1);
-
-  auto *MBB2 = MF->getBlockNumbered(2);
-  WE0 = WEI.getExceptionFor(MBB2);
-  ASSERT_TRUE(WE0);
-  EXPECT_EQ(WE0->getEHPad(), MBB1);
-
-  auto *MBB4 = MF->getBlockNumbered(4);
-  auto *WE0_0 = WEI.getExceptionFor(MBB4);
-  ASSERT_TRUE(WE0_0);
-  EXPECT_EQ(WE0_0->getEHPad(), MBB4);
-  EXPECT_EQ(WE0_0->getParentException(), WE0);
-  EXPECT_EQ(WE0_0->getExceptionDepth(), (unsigned)2);
-
-  auto *MBB5 = MF->getBlockNumbered(5);
-  WE0_0 = WEI.getExceptionFor(MBB5);
-  ASSERT_TRUE(WE0_0);
-  EXPECT_EQ(WE0_0->getEHPad(), MBB4);
-
-  auto *MBB6 = MF->getBlockNumbered(6);
-  auto *WE0_0_0 = WEI.getExceptionFor(MBB6);
-  ASSERT_TRUE(WE0_0_0);
-  EXPECT_EQ(WE0_0_0->getEHPad(), MBB6);
-  EXPECT_EQ(WE0_0_0->getParentException(), WE0_0);
-  EXPECT_EQ(WE0_0_0->getExceptionDepth(), (unsigned)3);
-
-  auto *MBB7 = MF->getBlockNumbered(7);
-  WE0_0_0 = WEI.getExceptionFor(MBB7);
-  ASSERT_TRUE(WE0_0_0);
-  EXPECT_EQ(WE0_0_0->getEHPad(), MBB6);
-}
diff --git a/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt b/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt
index d7208b2..924b7a2 100644
--- a/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/TextAPI/CMakeLists.txt
@@ -4,6 +4,8 @@
 
 add_llvm_unittest(TextAPITests
   ELFYAMLTest.cpp
+  TextStubV1Tests.cpp
+  TextStubV2Tests.cpp
 )
 
-target_link_libraries(TextAPITests PRIVATE LLVMTestingSupport)
+target_link_libraries(TextAPITests PRIVATE LLVMTestingSupport)
\ No newline at end of file
diff --git a/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp b/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp
index 1ace819..8217507 100644
--- a/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp
+++ b/src/llvm-project/llvm/unittests/TextAPI/ELFYAMLTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/TextAPI/YAMLTest.cpp --------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===-----------------------------------------------------------------------===/
 
@@ -150,7 +149,7 @@
       "--- !tapi-tbe\n"
       "TbeVersion:      1.0\n"
       "Arch:            AArch64\n"
-      "Symbols:         \n"
+      "Symbols:\n"
       "  bar:             { Type: Func, Weak: true }\n"
       "  foo:             { Type: NoType, Size: 99, Warning: Does nothing }\n"
       "  nor:             { Type: Func, Undefined: true }\n"
@@ -206,7 +205,7 @@
                           "TbeVersion:      1.0\n"
                           "SoName:          nosyms.so\n"
                           "Arch:            x86_64\n"
-                          "NeededLibs:      \n"
+                          "NeededLibs:\n"
                           "  - libc.so\n"
                           "  - libfoo.so\n"
                           "  - libbar.so\n"
diff --git a/src/llvm-project/llvm/unittests/TextAPI/TextStubV1Tests.cpp b/src/llvm-project/llvm/unittests/TextAPI/TextStubV1Tests.cpp
new file mode 100644
index 0000000..165e58f
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/TextAPI/TextStubV1Tests.cpp
@@ -0,0 +1,456 @@
+//===-- TextStubV1Tests.cpp - TBD V1 File Test ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------------===/
+
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+#include "llvm/TextAPI/MachO/TextAPIReader.h"
+#include "llvm/TextAPI/MachO/TextAPIWriter.h"
+#include "gtest/gtest.h"
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::MachO;
+
+struct ExportedSymbol {
+  SymbolKind Kind;
+  std::string Name;
+  bool WeakDefined;
+  bool ThreadLocalValue;
+};
+using ExportedSymbolSeq = std::vector<ExportedSymbol>;
+
+inline bool operator<(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+  return std::tie(lhs.Kind, lhs.Name) < std::tie(rhs.Kind, rhs.Name);
+}
+
+inline bool operator==(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+  return std::tie(lhs.Kind, lhs.Name, lhs.WeakDefined, lhs.ThreadLocalValue) ==
+         std::tie(rhs.Kind, rhs.Name, rhs.WeakDefined, rhs.ThreadLocalValue);
+}
+
+static ExportedSymbol TBDv1Symbols[] = {
+    {SymbolKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},
+    {SymbolKind::GlobalSymbol, "_sym1", false, false},
+    {SymbolKind::GlobalSymbol, "_sym2", false, false},
+    {SymbolKind::GlobalSymbol, "_sym3", false, false},
+    {SymbolKind::GlobalSymbol, "_sym4", false, false},
+    {SymbolKind::GlobalSymbol, "_sym5", false, false},
+    {SymbolKind::GlobalSymbol, "_tlv1", false, true},
+    {SymbolKind::GlobalSymbol, "_tlv2", false, true},
+    {SymbolKind::GlobalSymbol, "_tlv3", false, true},
+    {SymbolKind::GlobalSymbol, "_weak1", true, false},
+    {SymbolKind::GlobalSymbol, "_weak2", true, false},
+    {SymbolKind::GlobalSymbol, "_weak3", true, false},
+    {SymbolKind::ObjectiveCClass, "class1", false, false},
+    {SymbolKind::ObjectiveCClass, "class2", false, false},
+    {SymbolKind::ObjectiveCClass, "class3", false, false},
+    {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},
+    {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},
+    {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},
+};
+
+namespace TBDv1 {
+
+TEST(TBDv1, ReadFile) {
+  static const char tbd_v1_file1[] =
+      "---\n"
+      "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+      "platform: ios\n"
+      "install-name: Test.dylib\n"
+      "current-version: 2.3.4\n"
+      "compatibility-version: 1.0\n"
+      "swift-version: 1.1\n"
+      "exports:\n"
+      "  - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+      "    allowed-clients: [ clientA ]\n"
+      "    re-exports: [ /usr/lib/libfoo.dylib ]\n"
+      "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
+      "    objc-classes: [ _class1, _class2 ]\n"
+      "    objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
+      "    weak-def-symbols: [ _weak1, _weak2 ]\n"
+      "    thread-local-symbols: [ _tlv1, _tlv2 ]\n"
+      "  - archs: [ armv7, armv7s, armv7k ]\n"
+      "    symbols: [ _sym5 ]\n"
+      "    objc-classes: [ _class3 ]\n"
+      "    objc-ivars: [ _class1._ivar3 ]\n"
+      "    weak-def-symbols: [ _weak3 ]\n"
+      "    thread-local-symbols: [ _tlv3 ]\n"
+      "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_file1, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+  EXPECT_EQ(Archs, File->getArchitectures());
+  EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+  EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+  EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
+  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+  EXPECT_EQ(2U, File->getSwiftABIVersion());
+  EXPECT_EQ(ObjCConstraintType::None, File->getObjCConstraint());
+  EXPECT_TRUE(File->isTwoLevelNamespace());
+  EXPECT_TRUE(File->isApplicationExtensionSafe());
+  EXPECT_FALSE(File->isInstallAPI());
+  InterfaceFileRef client("clientA", Archs);
+  InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
+  EXPECT_EQ(1U, File->allowableClients().size());
+  EXPECT_EQ(client, File->allowableClients().front());
+  EXPECT_EQ(1U, File->reexportedLibraries().size());
+  EXPECT_EQ(reexport, File->reexportedLibraries().front());
+
+  ExportedSymbolSeq Exports;
+  for (const auto *Sym : File->symbols()) {
+    EXPECT_FALSE(Sym->isWeakReferenced());
+    EXPECT_FALSE(Sym->isUndefined());
+    Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName(),
+                                        Sym->isWeakDefined(),
+                                        Sym->isThreadLocalValue()});
+  }
+  llvm::sort(Exports.begin(), Exports.end());
+
+  EXPECT_EQ(sizeof(TBDv1Symbols) / sizeof(ExportedSymbol), Exports.size());
+  EXPECT_TRUE(
+      std::equal(Exports.begin(), Exports.end(), std::begin(TBDv1Symbols)));
+}
+
+TEST(TBDv1, ReadFile2) {
+  static const char tbd_v1_file2[] = "--- !tapi-tbd-v1\n"
+                                     "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+                                     "platform: ios\n"
+                                     "install-name: Test.dylib\n"
+                                     "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_file2, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+  EXPECT_EQ(Archs, File->getArchitectures());
+  EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+  EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
+  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+  EXPECT_EQ(0U, File->getSwiftABIVersion());
+  EXPECT_EQ(ObjCConstraintType::None, File->getObjCConstraint());
+  EXPECT_TRUE(File->isTwoLevelNamespace());
+  EXPECT_TRUE(File->isApplicationExtensionSafe());
+  EXPECT_FALSE(File->isInstallAPI());
+  EXPECT_EQ(0U, File->allowableClients().size());
+  EXPECT_EQ(0U, File->reexportedLibraries().size());
+}
+
+// Disable test for windows.
+#ifndef _WIN32
+TEST(TBDv1, WriteFile) {
+  static const char tbd_v1_file3[] =
+      "---\n"
+      "archs:           [ i386, x86_64 ]\n"
+      "platform:        macosx\n"
+      "install-name:    '/usr/lib/libfoo.dylib'\n"
+      "current-version: 1.2.3\n"
+      "compatibility-version: 0\n"
+      "swift-version:   5\n"
+      "objc-constraint: retain_release\n"
+      "exports:\n"
+      "  - archs:           [ i386 ]\n"
+      "    symbols:         [ _sym1 ]\n"
+      "    weak-def-symbols: [ _sym2 ]\n"
+      "    thread-local-symbols: [ _sym3 ]\n"
+      "  - archs:           [ x86_64 ]\n"
+      "    allowed-clients: [ clientA ]\n"
+      "    re-exports:      [ '/usr/lib/libfoo.dylib' ]\n"
+      "    symbols:         [ '_OBJC_EHTYPE_$_Class1' ]\n"
+      "    objc-classes:    [ _Class1 ]\n"
+      "    objc-ivars:      [ _Class1._ivar1 ]\n"
+      "...\n";
+
+  InterfaceFile File;
+  File.setPath("libfoo.dylib");
+  File.setInstallName("/usr/lib/libfoo.dylib");
+  File.setFileType(FileType::TBD_V1);
+  File.setArchitectures(AK_i386 | AK_x86_64);
+  File.setPlatform(PlatformKind::macOS);
+  File.setCurrentVersion(PackedVersion(1, 2, 3));
+  File.setSwiftABIVersion(5);
+  File.setObjCConstraint(ObjCConstraintType::Retain_Release);
+  File.addAllowableClient("clientA", AK_x86_64);
+  File.addReexportedLibrary("/usr/lib/libfoo.dylib", AK_x86_64);
+  File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", AK_i386);
+  File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", AK_i386,
+                 SymbolFlags::WeakDefined);
+  File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", AK_i386,
+                 SymbolFlags::ThreadLocalValue);
+  File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", AK_x86_64);
+  File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", AK_x86_64);
+  File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
+                 AK_x86_64);
+
+  SmallString<4096> Buffer;
+  raw_svector_ostream OS(Buffer);
+  auto Result = TextAPIWriter::writeToStream(OS, File);
+  EXPECT_FALSE(Result);
+  EXPECT_STREQ(tbd_v1_file3, Buffer.c_str());
+}
+
+TEST(TBDv1, Platform_macOS) {
+  static const char tbd_v1_platform_macos[] = "---\n"
+                                              "archs: [ x86_64 ]\n"
+                                              "platform: macosx\n"
+                                              "install-name: Test.dylib\n"
+                                              "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_macos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
+}
+#endif // _WIN32
+
+TEST(TBDv1, Platform_iOS) {
+  static const char tbd_v1_platform_ios[] = "---\n"
+                                            "archs: [ arm64 ]\n"
+                                            "platform: ios\n"
+                                            "install-name: Test.dylib\n"
+                                            "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_ios, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+}
+
+TEST(TBDv1, Platform_watchOS) {
+  static const char tbd_v1_platform_watchos[] = "---\n"
+                                                "archs: [ armv7k ]\n"
+                                                "platform: watchos\n"
+                                                "install-name: Test.dylib\n"
+                                                "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_watchos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
+}
+
+TEST(TBDv1, Platform_tvOS) {
+  static const char tbd_v1_platform_tvos[] = "---\n"
+                                             "archs: [ arm64 ]\n"
+                                             "platform: tvos\n"
+                                             "install-name: Test.dylib\n"
+                                             "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_tvos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
+}
+
+TEST(TBDv1, Platform_bridgeOS) {
+  static const char tbd_v1_platform_bridgeos[] = "---\n"
+                                                 "archs: [ armv7k ]\n"
+                                                 "platform: bridgeos\n"
+                                                 "install-name: Test.dylib\n"
+                                                 "...\n";
+
+  auto Buffer =
+      MemoryBuffer::getMemBuffer(tbd_v1_platform_bridgeos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
+}
+
+TEST(TBDv1, Swift_1_0) {
+  static const char tbd_v1_swift_1_0[] = "---\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 1.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(1U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_1_1) {
+  static const char tbd_v1_swift_1_1[] = "---\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 1.1\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_1, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(2U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_2_0) {
+  static const char tbd_v1_swift_2_0[] = "---\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 2.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_2_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(3U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_3_0) {
+  static const char tbd_v1_swift_3_0[] = "---\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 3.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_3_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(4U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_4_0) {
+  static const char tbd_v1_swift_4_0[] = "---\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 4.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_4_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI "
+            "version.\nswift-version: 4.0\n               ^~~\n",
+            errorMessage);
+}
+
+TEST(TBDv1, Swift_5) {
+  static const char tbd_v1_swift_5[] = "---\n"
+                                       "archs: [ arm64 ]\n"
+                                       "platform: ios\n"
+                                       "install-name: Test.dylib\n"
+                                       "swift-version: 5\n"
+                                       "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_5, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(5U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, Swift_99) {
+  static const char tbd_v1_swift_99[] = "---\n"
+                                        "archs: [ arm64 ]\n"
+                                        "platform: ios\n"
+                                        "install-name: Test.dylib\n"
+                                        "swift-version: 99\n"
+                                        "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_99, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V1, File->getFileType());
+  EXPECT_EQ(99U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv1, UnknownArchitecture) {
+  static const char tbd_v1_file_unknown_architecture[] =
+      "---\n"
+      "archs: [ foo ]\n"
+      "platform: macosx\n"
+      "install-name: Test.dylib\n"
+      "...\n";
+
+  auto Buffer =
+      MemoryBuffer::getMemBuffer(tbd_v1_file_unknown_architecture, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+}
+
+TEST(TBDv1, UnknownPlatform) {
+  static const char tbd_v1_file_unknown_platform[] = "---\n"
+                                                     "archs: [ i386 ]\n"
+                                                     "platform: newOS\n"
+                                                     "...\n";
+
+  auto Buffer =
+      MemoryBuffer::getMemBuffer(tbd_v1_file_unknown_platform, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
+            "newOS\n          ^~~~~\n",
+            errorMessage);
+}
+
+TEST(TBDv1, MalformedFile1) {
+  static const char malformed_file1[] = "---\n"
+                                        "archs: [ arm64 ]\n"
+                                        "foobar: \"Unsupported key\"\n"
+                                        "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(malformed_file1, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
+            "'platform'\narchs: [ arm64 ]\n^\n",
+            errorMessage);
+}
+
+TEST(TBDv1, MalformedFile2) {
+  static const char malformed_file2[] = "---\n"
+                                        "archs: [ arm64 ]\n"
+                                        "platform: ios\n"
+                                        "install-name: Test.dylib\n"
+                                        "foobar: \"Unsupported key\"\n"
+                                        "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(malformed_file2, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  ASSERT_EQ(
+      "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
+      "\"Unsupported key\"\n        ^~~~~~~~~~~~~~~~~\n",
+      errorMessage);
+}
+
+} // end namespace TBDv1.
diff --git a/src/llvm-project/llvm/unittests/TextAPI/TextStubV2Tests.cpp b/src/llvm-project/llvm/unittests/TextAPI/TextStubV2Tests.cpp
new file mode 100644
index 0000000..b4b8ca9
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/TextAPI/TextStubV2Tests.cpp
@@ -0,0 +1,481 @@
+//===-- TextStubV2Tests.cpp - TBD V2 File Test ----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===-----------------------------------------------------------------------===/
+
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+#include "llvm/TextAPI/MachO/TextAPIReader.h"
+#include "llvm/TextAPI/MachO/TextAPIWriter.h"
+#include "gtest/gtest.h"
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::MachO;
+
+struct ExportedSymbol {
+  SymbolKind Kind;
+  std::string Name;
+  bool WeakDefined;
+  bool ThreadLocalValue;
+};
+using ExportedSymbolSeq = std::vector<ExportedSymbol>;
+
+inline bool operator<(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+  return std::tie(lhs.Kind, lhs.Name) < std::tie(rhs.Kind, rhs.Name);
+}
+
+inline bool operator==(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
+  return std::tie(lhs.Kind, lhs.Name, lhs.WeakDefined, lhs.ThreadLocalValue) ==
+         std::tie(rhs.Kind, rhs.Name, rhs.WeakDefined, rhs.ThreadLocalValue);
+}
+
+static ExportedSymbol TBDv2Symbols[] = {
+    {SymbolKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},
+    {SymbolKind::GlobalSymbol, "_sym1", false, false},
+    {SymbolKind::GlobalSymbol, "_sym2", false, false},
+    {SymbolKind::GlobalSymbol, "_sym3", false, false},
+    {SymbolKind::GlobalSymbol, "_sym4", false, false},
+    {SymbolKind::GlobalSymbol, "_sym5", false, false},
+    {SymbolKind::GlobalSymbol, "_tlv1", false, true},
+    {SymbolKind::GlobalSymbol, "_tlv2", false, true},
+    {SymbolKind::GlobalSymbol, "_tlv3", false, true},
+    {SymbolKind::GlobalSymbol, "_weak1", true, false},
+    {SymbolKind::GlobalSymbol, "_weak2", true, false},
+    {SymbolKind::GlobalSymbol, "_weak3", true, false},
+    {SymbolKind::ObjectiveCClass, "class1", false, false},
+    {SymbolKind::ObjectiveCClass, "class2", false, false},
+    {SymbolKind::ObjectiveCClass, "class3", false, false},
+    {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},
+    {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},
+    {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},
+};
+
+namespace TBDv2 {
+
+TEST(TBDv2, ReadFile) {
+  static const char tbd_v2_file1[] =
+      "--- !tapi-tbd-v2\n"
+      "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+      "platform: ios\n"
+      "flags: [ installapi ]\n"
+      "install-name: Test.dylib\n"
+      "current-version: 2.3.4\n"
+      "compatibility-version: 1.0\n"
+      "swift-version: 1.1\n"
+      "parent-umbrella: Umbrella.dylib\n"
+      "exports:\n"
+      "  - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+      "    allowable-clients: [ clientA ]\n"
+      "    re-exports: [ /usr/lib/libfoo.dylib ]\n"
+      "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
+      "    objc-classes: [ _class1, _class2 ]\n"
+      "    objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
+      "    weak-def-symbols: [ _weak1, _weak2 ]\n"
+      "    thread-local-symbols: [ _tlv1, _tlv2 ]\n"
+      "  - archs: [ armv7, armv7s, armv7k ]\n"
+      "    symbols: [ _sym5 ]\n"
+      "    objc-classes: [ _class3 ]\n"
+      "    objc-ivars: [ _class1._ivar3 ]\n"
+      "    weak-def-symbols: [ _weak3 ]\n"
+      "    thread-local-symbols: [ _tlv3 ]\n"
+      "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v2_file1, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+  EXPECT_EQ(Archs, File->getArchitectures());
+  EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+  EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+  EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
+  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+  EXPECT_EQ(2U, File->getSwiftABIVersion());
+  EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
+  EXPECT_TRUE(File->isTwoLevelNamespace());
+  EXPECT_TRUE(File->isApplicationExtensionSafe());
+  EXPECT_TRUE(File->isInstallAPI());
+  InterfaceFileRef client("clientA", Archs);
+  InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
+  EXPECT_EQ(1U, File->allowableClients().size());
+  EXPECT_EQ(client, File->allowableClients().front());
+  EXPECT_EQ(1U, File->reexportedLibraries().size());
+  EXPECT_EQ(reexport, File->reexportedLibraries().front());
+
+  ExportedSymbolSeq Exports;
+  for (const auto *Sym : File->symbols()) {
+    EXPECT_FALSE(Sym->isWeakReferenced());
+    EXPECT_FALSE(Sym->isUndefined());
+    Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName(),
+                                        Sym->isWeakDefined(),
+                                        Sym->isThreadLocalValue()});
+  }
+  llvm::sort(Exports.begin(), Exports.end());
+
+  EXPECT_EQ(sizeof(TBDv2Symbols) / sizeof(ExportedSymbol), Exports.size());
+  EXPECT_TRUE(
+      std::equal(Exports.begin(), Exports.end(), std::begin(TBDv2Symbols)));
+}
+
+TEST(TBDv2, ReadFile2) {
+  static const char tbd_v2_file2[] =
+      "--- !tapi-tbd-v2\n"
+      "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+      "platform: ios\n"
+      "flags: [ flat_namespace, not_app_extension_safe ]\n"
+      "install-name: Test.dylib\n"
+      "swift-version: 1.1\n"
+      "exports:\n"
+      "  - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+      "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
+      "    objc-classes: [ _class1, _class2 ]\n"
+      "    objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
+      "    weak-def-symbols: [ _weak1, _weak2 ]\n"
+      "    thread-local-symbols: [ _tlv1, _tlv2 ]\n"
+      "  - archs: [ armv7, armv7s, armv7k ]\n"
+      "    symbols: [ _sym5 ]\n"
+      "    objc-classes: [ _class3 ]\n"
+      "    objc-ivars: [ _class1._ivar3 ]\n"
+      "    weak-def-symbols: [ _weak3 ]\n"
+      "    thread-local-symbols: [ _tlv3 ]\n"
+      "undefineds:\n"
+      "  - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
+      "    symbols: [ _undefSym1, _undefSym2, _undefSym3 ]\n"
+      "    objc-classes: [ _undefClass1, _undefClass2 ]\n"
+      "    objc-ivars: [ _undefClass1._ivar1, _undefClass1._ivar2 ]\n"
+      "    weak-ref-symbols: [ _undefWeak1, _undefWeak2 ]\n"
+      "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v2_file2, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
+  EXPECT_EQ(Archs, File->getArchitectures());
+  EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+  EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
+  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
+  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
+  EXPECT_EQ(2U, File->getSwiftABIVersion());
+  EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
+  EXPECT_FALSE(File->isTwoLevelNamespace());
+  EXPECT_FALSE(File->isApplicationExtensionSafe());
+  EXPECT_FALSE(File->isInstallAPI());
+  EXPECT_EQ(0U, File->allowableClients().size());
+  EXPECT_EQ(0U, File->reexportedLibraries().size());
+}
+
+// Disable test for windows.
+#ifndef _WIN32
+TEST(TBDv2, WriteFile) {
+  static const char tbd_v2_file3[] =
+      "--- !tapi-tbd-v2\n"
+      "archs:           [ i386, x86_64 ]\n"
+      "platform:        macosx\n"
+      "install-name:    '/usr/lib/libfoo.dylib'\n"
+      "current-version: 1.2.3\n"
+      "compatibility-version: 0\n"
+      "swift-version:   5\n"
+      "exports:\n"
+      "  - archs:           [ i386 ]\n"
+      "    symbols:         [ _sym1 ]\n"
+      "    weak-def-symbols: [ _sym2 ]\n"
+      "    thread-local-symbols: [ _sym3 ]\n"
+      "  - archs:           [ x86_64 ]\n"
+      "    allowable-clients: [ clientA ]\n"
+      "    re-exports:      [ '/usr/lib/libfoo.dylib' ]\n"
+      "    symbols:         [ '_OBJC_EHTYPE_$_Class1' ]\n"
+      "    objc-classes:    [ _Class1 ]\n"
+      "    objc-ivars:      [ _Class1._ivar1 ]\n"
+      "...\n";
+
+  InterfaceFile File;
+  File.setPath("libfoo.dylib");
+  File.setInstallName("/usr/lib/libfoo.dylib");
+  File.setFileType(FileType::TBD_V2);
+  File.setArchitectures(AK_i386 | AK_x86_64);
+  File.setPlatform(PlatformKind::macOS);
+  File.setCurrentVersion(PackedVersion(1, 2, 3));
+  File.setTwoLevelNamespace();
+  File.setApplicationExtensionSafe();
+  File.setSwiftABIVersion(5);
+  File.setObjCConstraint(ObjCConstraintType::Retain_Release);
+  File.addAllowableClient("clientA", AK_x86_64);
+  File.addReexportedLibrary("/usr/lib/libfoo.dylib", AK_x86_64);
+  File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", AK_i386);
+  File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", AK_i386,
+                 SymbolFlags::WeakDefined);
+  File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", AK_i386,
+                 SymbolFlags::ThreadLocalValue);
+  File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", AK_x86_64);
+  File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", AK_x86_64);
+  File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
+                 AK_x86_64);
+
+  SmallString<4096> Buffer;
+  raw_svector_ostream OS(Buffer);
+  auto Result = TextAPIWriter::writeToStream(OS, File);
+  EXPECT_FALSE(Result);
+  EXPECT_STREQ(tbd_v2_file3, Buffer.c_str());
+}
+#endif // _WIN32
+
+TEST(TBDv2, Platform_macOS) {
+  static const char tbd_v1_platform_macos[] = "--- !tapi-tbd-v2\n"
+                                              "archs: [ x86_64 ]\n"
+                                              "platform: macosx\n"
+                                              "install-name: Test.dylib\n"
+                                              "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_macos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_iOS) {
+  static const char tbd_v1_platform_ios[] = "--- !tapi-tbd-v2\n"
+                                            "archs: [ arm64 ]\n"
+                                            "platform: ios\n"
+                                            "install-name: Test.dylib\n"
+                                            "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_ios, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_watchOS) {
+  static const char tbd_v1_platform_watchos[] = "--- !tapi-tbd-v2\n"
+                                                "archs: [ armv7k ]\n"
+                                                "platform: watchos\n"
+                                                "install-name: Test.dylib\n"
+                                                "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_watchos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_tvOS) {
+  static const char tbd_v1_platform_tvos[] = "--- !tapi-tbd-v2\n"
+                                             "archs: [ arm64 ]\n"
+                                             "platform: tvos\n"
+                                             "install-name: Test.dylib\n"
+                                             "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_tvos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
+}
+
+TEST(TBDv2, Platform_bridgeOS) {
+  static const char tbd_v1_platform_bridgeos[] = "--- !tapi-tbd-v2\n"
+                                                 "archs: [ armv7k ]\n"
+                                                 "platform: bridgeos\n"
+                                                 "install-name: Test.dylib\n"
+                                                 "...\n";
+
+  auto Buffer =
+      MemoryBuffer::getMemBuffer(tbd_v1_platform_bridgeos, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
+}
+
+TEST(TBDv2, Swift_1_0) {
+  static const char tbd_v1_swift_1_0[] = "--- !tapi-tbd-v2\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 1.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(1U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_1_1) {
+  static const char tbd_v1_swift_1_1[] = "--- !tapi-tbd-v2\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 1.1\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_1, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(2U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_2_0) {
+  static const char tbd_v1_swift_2_0[] = "--- !tapi-tbd-v2\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 2.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_2_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(3U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_3_0) {
+  static const char tbd_v1_swift_3_0[] = "--- !tapi-tbd-v2\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 3.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_3_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(4U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_4_0) {
+  static const char tbd_v1_swift_4_0[] = "--- !tapi-tbd-v2\n"
+                                         "archs: [ arm64 ]\n"
+                                         "platform: ios\n"
+                                         "install-name: Test.dylib\n"
+                                         "swift-version: 4.0\n"
+                                         "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_4_0, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI "
+            "version.\nswift-version: 4.0\n               ^~~\n",
+            errorMessage);
+}
+
+TEST(TBDv2, Swift_5) {
+  static const char tbd_v1_swift_5[] = "--- !tapi-tbd-v2\n"
+                                       "archs: [ arm64 ]\n"
+                                       "platform: ios\n"
+                                       "install-name: Test.dylib\n"
+                                       "swift-version: 5\n"
+                                       "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_5, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(5U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, Swift_99) {
+  static const char tbd_v1_swift_99[] = "--- !tapi-tbd-v2\n"
+                                        "archs: [ arm64 ]\n"
+                                        "platform: ios\n"
+                                        "install-name: Test.dylib\n"
+                                        "swift-version: 99\n"
+                                        "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_99, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+  auto File = std::move(Result.get());
+  EXPECT_EQ(FileType::TBD_V2, File->getFileType());
+  EXPECT_EQ(99U, File->getSwiftABIVersion());
+}
+
+TEST(TBDv2, UnknownArchitecture) {
+  static const char tbd_v2_file_unknown_architecture[] =
+      "--- !tapi-tbd-v2\n"
+      "archs: [ foo ]\n"
+      "platform: macosx\n"
+      "install-name: Test.dylib\n"
+      "...\n";
+
+  auto Buffer =
+      MemoryBuffer::getMemBuffer(tbd_v2_file_unknown_architecture, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_TRUE(!!Result);
+}
+
+TEST(TBDv2, UnknownPlatform) {
+  static const char tbd_v2_file_unknown_platform[] = "--- !tapi-tbd-v2\n"
+                                                     "archs: [ i386 ]\n"
+                                                     "platform: newOS\n"
+                                                     "...\n";
+
+  auto Buffer =
+      MemoryBuffer::getMemBuffer(tbd_v2_file_unknown_platform, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
+            "newOS\n          ^~~~~\n",
+            errorMessage);
+}
+
+TEST(TBDv2, MalformedFile1) {
+  static const char malformed_file1[] = "--- !tapi-tbd-v2\n"
+                                        "archs: [ arm64 ]\n"
+                                        "foobar: \"Unsupported key\"\n"
+                                        "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(malformed_file1, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
+            "'platform'\narchs: [ arm64 ]\n^\n",
+            errorMessage);
+}
+
+TEST(TBDv2, MalformedFile2) {
+  static const char malformed_file2[] = "--- !tapi-tbd-v2\n"
+                                        "archs: [ arm64 ]\n"
+                                        "platform: ios\n"
+                                        "install-name: Test.dylib\n"
+                                        "foobar: \"Unsupported key\"\n"
+                                        "...\n";
+
+  auto Buffer = MemoryBuffer::getMemBuffer(malformed_file2, "Test.tbd");
+  auto Result = TextAPIReader::get(std::move(Buffer));
+  EXPECT_FALSE(!!Result);
+  auto errorMessage = toString(Result.takeError());
+  ASSERT_EQ(
+      "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
+      "\"Unsupported key\"\n        ^~~~~~~~~~~~~~~~~\n",
+      errorMessage);
+}
+
+} // namespace TBDv2
diff --git a/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp b/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp
index 66c9de6..ba13378 100644
--- a/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/IPO/LowerTypeTests.cpp
@@ -1,9 +1,8 @@
 //===- LowerTypeTests.cpp - Unit tests for type test lowering -------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp b/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp
index 7e7a6bf..8fae05b 100644
--- a/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/IPO/WholeProgramDevirt.cpp
@@ -1,9 +1,8 @@
 //===- WholeProgramDevirt.cpp - Unit tests for whole-program devirt -------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt b/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt
index 2762799..3d01d5c 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Transforms/Scalar/CMakeLists.txt
@@ -10,3 +10,8 @@
 add_llvm_unittest(ScalarTests
   LoopPassManagerTest.cpp
   )
+
+# Workaround for the gcc 6.1 bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80916.
+if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
+  set_source_files_properties(LoopPassManagerTest.cpp PROPERTIES COMPILE_FLAGS -Wno-unused-function)
+endif()
diff --git a/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
index 9f0b6f0..5eb8101 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Analysis/LoopPassManagerTest.cpp - LPM tests ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -21,19 +20,9 @@
 #include "llvm/IR/PassManager.h"
 #include "llvm/Support/SourceMgr.h"
 
-// Workaround for the gcc 6.1 bug PR80916.
-#if defined(__GNUC__) && __GNUC__ > 5
-#  pragma GCC diagnostic push
-#  pragma GCC diagnostic ignored "-Wunused-function"
-#endif
-
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-#if defined(__GNUC__) && __GNUC__ > 5
-#  pragma GCC diagnostic pop
-#endif
-
 using namespace llvm;
 
 namespace {
@@ -304,6 +293,8 @@
     // those.
     FAM.registerPass([&] { return AAManager(); });
     FAM.registerPass([&] { return AssumptionAnalysis(); });
+    if (EnableMSSALoopDependency)
+      FAM.registerPass([&] { return MemorySSAAnalysis(); });
     FAM.registerPass([&] { return ScalarEvolutionAnalysis(); });
     FAM.registerPass([&] { return TargetLibraryAnalysis(); });
     FAM.registerPass([&] { return TargetIRAnalysis(); });
@@ -405,11 +396,13 @@
   // No need to re-run if we require again from a fresh loop pass manager.
   FPM.addPass(createFunctionToLoopPassAdaptor(
       RequireAnalysisLoopPass<MockLoopAnalysisHandle::Analysis>()));
-
   // For 'f', preserve most things but not the specific loop analyses.
+  auto PA = getLoopPassPreservedAnalyses();
+  if (EnableMSSALoopDependency)
+    PA.preserve<MemorySSAAnalysis>();
   EXPECT_CALL(MFPHandle, run(HasName("f"), _))
       .InSequence(FSequence)
-      .WillOnce(Return(getLoopPassPreservedAnalyses()));
+      .WillOnce(Return(PA));
   EXPECT_CALL(MLAHandle, invalidate(HasName("loop.0.0"), _, _))
       .InSequence(FSequence)
       .WillOnce(DoDefault());
@@ -484,6 +477,8 @@
   EXPECT_CALL(MMPHandle, run(_, _)).WillOnce(InvokeWithoutArgs([] {
     auto PA = getLoopPassPreservedAnalyses();
     PA.preserve<FunctionAnalysisManagerModuleProxy>();
+    if (EnableMSSALoopDependency)
+      PA.preserve<MemorySSAAnalysis>();
     return PA;
   }));
   // All the loop analyses from both functions get invalidated before we
@@ -571,7 +566,6 @@
   // invalidation and running.
   EXPECT_CALL(MFPHandle, run(HasName("f"), _))
       .WillOnce(Return(getLoopPassPreservedAnalyses()));
-  EXPECT_CALL(MLAHandle, invalidate(_, _, _)).Times(3);
   EXPECT_CALL(MLAHandle, run(HasName("loop.0.0"), _, _));
   EXPECT_CALL(MLAHandle, run(HasName("loop.0.1"), _, _));
   EXPECT_CALL(MLAHandle, run(HasName("loop.0"), _, _));
@@ -813,6 +807,8 @@
   // the fact that they were preserved.
   EXPECT_CALL(MFPHandle, run(HasName("f"), _)).WillOnce(InvokeWithoutArgs([] {
     auto PA = getLoopPassPreservedAnalyses();
+    if (EnableMSSALoopDependency)
+      PA.preserve<MemorySSAAnalysis>();
     PA.preserveSet<AllAnalysesOn<Loop>>();
     return PA;
   }));
@@ -834,6 +830,8 @@
   // Which means that no extra invalidation occurs and cached values are used.
   EXPECT_CALL(MFPHandle, run(HasName("g"), _)).WillOnce(InvokeWithoutArgs([] {
     auto PA = getLoopPassPreservedAnalyses();
+    if (EnableMSSALoopDependency)
+      PA.preserve<MemorySSAAnalysis>();
     PA.preserveSet<AllAnalysesOn<Loop>>();
     return PA;
   }));
@@ -909,7 +907,8 @@
   ASSERT_THAT(BBI, F.end());
   auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
                           const char *Name, BasicBlock *BB) {
-    auto *Cond = new LoadInst(&Ptr, Name, /*isVolatile*/ true, BB);
+    auto *Cond = new LoadInst(Type::getInt1Ty(Context), &Ptr, Name,
+                              /*isVolatile*/ true, BB);
     BranchInst::Create(TrueBB, FalseBB, Cond, BB);
   };
 
@@ -1111,7 +1110,8 @@
   ASSERT_THAT(BBI, F.end());
   auto CreateCondBr = [&](BasicBlock *TrueBB, BasicBlock *FalseBB,
                           const char *Name, BasicBlock *BB) {
-    auto *Cond = new LoadInst(&Ptr, Name, /*isVolatile*/ true, BB);
+    auto *Cond = new LoadInst(Type::getInt1Ty(Context), &Ptr, Name,
+                              /*isVolatile*/ true, BB);
     BranchInst::Create(TrueBB, FalseBB, Cond, BB);
   };
 
@@ -1504,8 +1504,9 @@
             auto *NewLoop03BB =
                 BasicBlock::Create(Context, "loop.0.3", &F, &Loop0LatchBB);
             BranchInst::Create(NewLoop03BB, NewLoop03PHBB);
-            auto *Cond = new LoadInst(&Ptr, "cond.0.3", /*isVolatile*/ true,
-                                      NewLoop03BB);
+            auto *Cond =
+                new LoadInst(Type::getInt1Ty(Context), &Ptr, "cond.0.3",
+                             /*isVolatile*/ true, NewLoop03BB);
             BranchInst::Create(&Loop0LatchBB, NewLoop03BB, Cond, NewLoop03BB);
             Loop02PHBB.getTerminator()->replaceUsesOfWith(&Loop0LatchBB,
                                                           NewLoop03PHBB);
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
index 777918e..8af49c6 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/ASanStackFrameLayoutTest.cpp
@@ -1,9 +1,8 @@
 //===- ASanStackFrameLayoutTest.cpp - Tests for ComputeASanStackFrameLayout===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
index 2d0a930..bf8228e 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
@@ -1,13 +1,13 @@
 //===- BasicBlockUtils.cpp - Unit tests for BasicBlockUtils ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Analysis/PostDominators.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Dominators.h"
@@ -25,6 +25,64 @@
   return Mod;
 }
 
+TEST(BasicBlockUtils, EliminateUnreachableBlocks) {
+  LLVMContext C;
+
+  std::unique_ptr<Module> M = parseIR(
+    C,
+    "define i32 @has_unreachable(i1 %cond) {\n"
+    "entry:\n"
+    "  br i1 %cond, label %bb0, label %bb1\n"
+    "bb0:\n"
+    "  br label %bb1\n"
+    "bb1:\n"
+    "  %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]"
+    "  ret i32 %phi\n"
+    "bb2:\n"
+    "  ret i32 42\n"
+    "}\n"
+    "\n"
+    );
+
+  auto *F = M->getFunction("has_unreachable");
+  DominatorTree DT(*F);
+  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+  EXPECT_EQ(F->size(), (size_t)4);
+  bool Result = EliminateUnreachableBlocks(*F, &DTU);
+  EXPECT_TRUE(Result);
+  EXPECT_EQ(F->size(), (size_t)3);
+  EXPECT_TRUE(DT.verify());
+}
+
+TEST(BasicBlockUtils, NoUnreachableBlocksToEliminate) {
+  LLVMContext C;
+
+  std::unique_ptr<Module> M = parseIR(
+    C,
+    "define i32 @no_unreachable(i1 %cond) {\n"
+    "entry:\n"
+    "  br i1 %cond, label %bb0, label %bb1\n"
+    "bb0:\n"
+    "  br label %bb1\n"
+    "bb1:\n"
+    "  %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]"
+    "  ret i32 %phi\n"
+    "}\n"
+    "\n"
+    );
+
+  auto *F = M->getFunction("no_unreachable");
+  DominatorTree DT(*F);
+  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+  EXPECT_EQ(F->size(), (size_t)3);
+  bool Result = EliminateUnreachableBlocks(*F, &DTU);
+  EXPECT_FALSE(Result);
+  EXPECT_EQ(F->size(), (size_t)3);
+  EXPECT_TRUE(DT.verify());
+}
+
 TEST(BasicBlockUtils, SplitBlockPredecessors) {
   LLVMContext C;
 
@@ -50,3 +108,31 @@
   SplitBlockPredecessors(&F->getEntryBlock(), {}, "split.entry", &DT);
   EXPECT_TRUE(DT.verify());
 }
+
+TEST(BasicBlockUtils, SplitCriticalEdge) {
+  LLVMContext C;
+
+  std::unique_ptr<Module> M = parseIR(
+    C,
+    "define void @crit_edge(i1 %cond0, i1 %cond1) {\n"
+    "entry:\n"
+    "  br i1 %cond0, label %bb0, label %bb1\n"
+    "bb0:\n"
+    "  br label %bb1\n"
+    "bb1:\n"
+    "  br label %bb2\n"
+    "bb2:\n"
+    "  ret void\n"
+    "}\n"
+    "\n"
+    );
+
+  auto *F = M->getFunction("crit_edge");
+  DominatorTree DT(*F);
+  PostDominatorTree PDT(*F);
+
+  CriticalEdgeSplittingOptions CESO(&DT, nullptr, nullptr, &PDT);
+  EXPECT_EQ(1u, SplitAllCriticalEdges(*F, CESO));
+  EXPECT_TRUE(DT.verify());
+  EXPECT_TRUE(PDT.verify());
+}
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp
index 9d6bf0a..514a770 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/CloningTest.cpp
@@ -1,20 +1,21 @@
 //===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/Argument.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/DomTreeUpdater.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InstIterator.h"
@@ -356,6 +357,91 @@
   delete F;
 }
 
+static void runWithLoopInfoAndDominatorTree(
+    Module &M, StringRef FuncName,
+    function_ref<void(Function &F, LoopInfo &LI, DominatorTree &DT)> Test) {
+  auto *F = M.getFunction(FuncName);
+  ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
+
+  DominatorTree DT(*F);
+  LoopInfo LI(DT);
+
+  Test(*F, LI, DT);
+}
+
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+  SMDiagnostic Err;
+  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+  if (!Mod)
+    Err.print("CloneLoop", errs());
+  return Mod;
+}
+
+TEST(CloneLoop, CloneLoopNest) {
+  // Parse the module.
+  LLVMContext Context;
+
+  std::unique_ptr<Module> M = parseIR(
+    Context,
+    R"(define void @foo(i32* %A, i32 %ub) {
+entry:
+  %guardcmp = icmp slt i32 0, %ub
+  br i1 %guardcmp, label %for.outer.preheader, label %for.end
+for.outer.preheader:
+  br label %for.outer
+for.outer:
+  %j = phi i32 [ 0, %for.outer.preheader ], [ %inc.outer, %for.outer.latch ]
+  br i1 %guardcmp, label %for.inner.preheader, label %for.outer.latch
+for.inner.preheader:
+  br label %for.inner
+for.inner:
+  %i = phi i32 [ 0, %for.inner.preheader ], [ %inc, %for.inner ]
+  %idxprom = sext i32 %i to i64
+  %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
+  store i32 %i, i32* %arrayidx, align 4
+  %inc = add nsw i32 %i, 1
+  %cmp = icmp slt i32 %inc, %ub
+  br i1 %cmp, label %for.inner, label %for.inner.exit
+for.inner.exit:
+  br label %for.outer.latch
+for.outer.latch:
+  %inc.outer = add nsw i32 %j, 1
+  %cmp.outer = icmp slt i32 %inc.outer, %ub
+  br i1 %cmp.outer, label %for.outer, label %for.outer.exit
+for.outer.exit:
+  br label %for.end
+for.end:
+  ret void
+})"
+    );
+
+  runWithLoopInfoAndDominatorTree(
+      *M, "foo", [&](Function &F, LoopInfo &LI, DominatorTree &DT) {
+        Function::iterator FI = F.begin();
+        // First basic block is entry - skip it.
+        BasicBlock *Preheader = &*(++FI);
+        BasicBlock *Header = &*(++FI);
+        assert(Header->getName() == "for.outer");
+        Loop *L = LI.getLoopFor(Header);
+        EXPECT_NE(L, nullptr);
+        EXPECT_EQ(Header, L->getHeader());
+        EXPECT_EQ(Preheader, L->getLoopPreheader());
+
+        ValueToValueMapTy VMap;
+        SmallVector<BasicBlock *, 4> ClonedLoopBlocks;
+        Loop *NewLoop = cloneLoopWithPreheader(Preheader, Preheader, L, VMap,
+                                               "", &LI, &DT, ClonedLoopBlocks);
+        EXPECT_NE(NewLoop, nullptr);
+        EXPECT_EQ(NewLoop->getSubLoops().size(), 1u);
+        Loop::block_iterator BI = NewLoop->block_begin();
+        EXPECT_TRUE((*BI)->getName().startswith("for.outer"));
+        EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.preheader"));
+        EXPECT_TRUE((*(++BI))->getName().startswith("for.inner"));
+        EXPECT_TRUE((*(++BI))->getName().startswith("for.inner.exit"));
+        EXPECT_TRUE((*(++BI))->getName().startswith("for.outer.latch"));
+      });
+}
+
 class CloneFunc : public ::testing::Test {
 protected:
   void SetUp() override {
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp
index 7e3512f..8b86951 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp
@@ -1,9 +1,8 @@
 //===- CodeExtractor.cpp - Unit tests for CodeExtractor -------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -59,8 +58,7 @@
                                            getBlockByName(Func, "body1"),
                                            getBlockByName(Func, "body2") };
 
-  DominatorTree DT(*Func);
-  CodeExtractor CE(Candidates, &DT);
+  CodeExtractor CE(Candidates);
   EXPECT_TRUE(CE.isEligible());
 
   Function *Outlined = CE.extractCodeRegion();
@@ -110,8 +108,7 @@
     getBlockByName(Func, "extracted2")
   };
 
-  DominatorTree DT(*Func);
-  CodeExtractor CE(ExtractedBlocks, &DT);
+  CodeExtractor CE(ExtractedBlocks);
   EXPECT_TRUE(CE.isEligible());
 
   Function *Outlined = CE.extractCodeRegion();
@@ -185,8 +182,7 @@
     getBlockByName(Func, "lpad2")
   };
 
-  DominatorTree DT(*Func);
-  CodeExtractor CE(ExtractedBlocks, &DT);
+  CodeExtractor CE(ExtractedBlocks);
   EXPECT_TRUE(CE.isEligible());
 
   Function *Outlined = CE.extractCodeRegion();
@@ -195,4 +191,38 @@
   EXPECT_FALSE(verifyFunction(*Func, &errs()));
 }
 
+TEST(CodeExtractor, StoreOutputInvokeResultInExitStub) {
+  LLVMContext Ctx;
+  SMDiagnostic Err;
+  std::unique_ptr<Module> M(parseAssemblyString(R"invalid(
+    declare i32 @bar()
+
+    define i32 @foo() personality i8* null {
+    entry:
+      %0 = invoke i32 @bar() to label %exit unwind label %lpad
+
+    exit:
+      ret i32 %0
+
+    lpad:
+      %1 = landingpad { i8*, i32 }
+              cleanup
+      resume { i8*, i32 } %1
+    }
+  )invalid",
+                                                Err, Ctx));
+
+  Function *Func = M->getFunction("foo");
+  SmallVector<BasicBlock *, 1> Blocks{ getBlockByName(Func, "entry"),
+                                       getBlockByName(Func, "lpad") };
+
+  CodeExtractor CE(Blocks);
+  EXPECT_TRUE(CE.isEligible());
+
+  Function *Outlined = CE.extractCodeRegion();
+  EXPECT_TRUE(Outlined);
+  EXPECT_FALSE(verifyFunction(*Outlined));
+  EXPECT_FALSE(verifyFunction(*Func));
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp
index 26e20cd..42f9fb3 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp
@@ -1,9 +1,8 @@
 //===- FunctionComparator.cpp - Unit tests for FunctionComparator ---------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/Transforms/Utils/FunctionComparator.h"
@@ -32,7 +31,7 @@
     BB = BasicBlock::Create(Ctx, "", F);
     B.SetInsertPoint(BB);
     Argument *PointerArg = &*F->arg_begin();
-    LoadInst *LoadInst = B.CreateLoad(PointerArg);
+    LoadInst *LoadInst = B.CreateLoad(T, PointerArg);
     C = B.getInt8(addVal);
     I = cast<Instruction>(B.CreateAdd(LoadInst, C));
     B.CreateRet(I);
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp
index e337b9f..7994673 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/IntegerDivisionTest.cpp
@@ -1,9 +1,8 @@
 //===- IntegerDivision.cpp - Unit tests for the integer division code -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp
index 3868bfb..55f04e9 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/LocalTest.cpp
@@ -1,18 +1,17 @@
 //===- Local.cpp - Unit tests for Local -----------------------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Analysis/DomTreeUpdater.h"
 #include "llvm/Analysis/PostDominators.h"
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DomTreeUpdater.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
@@ -154,8 +153,7 @@
   ASSERT_TRUE(DII);
   Value *NewBase = Constant::getNullValue(Type::getInt32PtrTy(C));
   DIBuilder DIB(*M);
-  replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::NoDeref, 0,
-                    DIExpression::NoDeref);
+  replaceDbgDeclare(AI, NewBase, DII, DIB, DIExpression::ApplyOffset, 0);
 
   // There should be exactly two dbg.declares.
   int Declares = 0;
@@ -789,31 +787,35 @@
   };
 
   // Case 1: The original expr is empty, so no deref is needed.
-  EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
-                          DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value}));
 
   // Case 2: Perform an address calculation with the original expr, deref it,
   // then sign-extend the result.
-  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup,
-                          DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0, DW_OP_not,
-                          DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
+                         DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value}));
 
   // Case 3: Insert the sign-extension logic before the DW_OP_stack_value.
-  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
-                          DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
-                          DW_OP_stack_value}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
+                         DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value}));
 
   // Cases 4-6: Just like cases 1-3, but preserve the fragment at the end.
-  EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
-                          DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value,
-                          DW_OP_LLVM_fragment, 0, 8}));
-  EXPECT_TRUE(
-      hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup, DW_OP_constu,
-                  31, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
-                  DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
-  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
-                          DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
-                          DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
+                         DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
+                         DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
 
   verifyModule(*M, &errs(), &BrokenDebugInfo);
   ASSERT_FALSE(BrokenDebugInfo);
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp
index 61cbcb7..b75a492 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/SSAUpdaterBulkTest.cpp
@@ -1,9 +1,8 @@
 //===- SSAUpdaterBulk.cpp - Unit tests for SSAUpdaterBulk -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp
index 5f7c2d6..fba21a7 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/UnrollLoopTest.cpp
@@ -1,9 +1,8 @@
 //===- UnrollLoopTest.cpp - Unit tests for UnrollLoop ---------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -71,6 +70,7 @@
 
   bool PreserveLCSSA = L->isRecursivelyLCSSAForm(DT,LI);
 
-  bool ret = UnrollRuntimeLoopRemainder(L, 4, true, false, false, &LI, &SE, &DT, &AC, PreserveLCSSA);
+  bool ret = UnrollRuntimeLoopRemainder(L, 4, true, false, false, false, &LI,
+                                        &SE, &DT, &AC, PreserveLCSSA);
   EXPECT_FALSE(ret);
 }
diff --git a/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp
index 94ac76b..690f434 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp
@@ -1,9 +1,8 @@
 //===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt b/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
index 6e886bb..74fc5ed 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
@@ -8,6 +8,7 @@
 add_llvm_unittest(VectorizeTests
   VPlanDominatorTreeTest.cpp
   VPlanLoopInfoTest.cpp
+  VPlanPredicatorTest.cpp
   VPlanTest.cpp
   VPlanHCFGTest.cpp
   VPlanSlpTest.cpp
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp
index 57f07392..6f39790 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp
index 215c3ef..f5894a4 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Transforms/Vectorize/VPlanHCFGTest.cpp ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
index 55486ba..0bb4599 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp -----===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp
new file mode 100644
index 0000000..81ed3ce
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp
@@ -0,0 +1,229 @@
+//===- llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../lib/Transforms/Vectorize/VPlanPredicator.h"
+#include "VPlanTestBase.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+class VPlanPredicatorTest : public VPlanTestBase {};
+
+TEST_F(VPlanPredicatorTest, BasicPredicatorTest) {
+  const char *ModuleString =
+      "@arr = common global [8 x [8 x i64]] "
+      "zeroinitializer, align 16\n"
+      "@arr2 = common global [8 x [8 x i64]] "
+      "zeroinitializer, align 16\n"
+      "@arr3 = common global [8 x [8 x i64]] "
+      "zeroinitializer, align 16\n"
+      "define void @f(i64 %n1) {\n"
+      "entry:\n"
+      "  br label %for.cond1.preheader\n"
+      "for.cond1.preheader:                              \n"
+      "  %i1.029 = phi i64 [ 0, %entry ], [ %inc14, %for.inc13 ]\n"
+      "  br label %for.body3\n"
+      "for.body3:                                        \n"
+      "  %i2.028 = phi i64 [ 0, %for.cond1.preheader ], [ %inc, %for.inc ]\n"
+      "  %arrayidx4 = getelementptr inbounds [8 x [8 x i64]], [8 x [8 x i64]]* "
+      "@arr, i64 0, i64 %i2.028, i64 %i1.029\n"
+      "  %0 = load i64, i64* %arrayidx4, align 8\n"
+      "  %cmp5 = icmp ugt i64 %0, 10\n"
+      "  br i1 %cmp5, label %if.then, label %for.inc\n"
+      "if.then:                                          \n"
+      "  %arrayidx7 = getelementptr inbounds [8 x [8 x i64]], [8 x [8 x i64]]* "
+      "@arr2, i64 0, i64 %i2.028, i64 %i1.029\n"
+      "  %1 = load i64, i64* %arrayidx7, align 8\n"
+      "  %cmp8 = icmp ugt i64 %1, 100\n"
+      "  br i1 %cmp8, label %if.then9, label %for.inc\n"
+      "if.then9:                                         \n"
+      "  %add = add nuw nsw i64 %i2.028, %i1.029\n"
+      "  %arrayidx11 = getelementptr inbounds [8 x [8 x i64]], [8 x [8 x "
+      "i64]]* @arr3, i64 0, i64 %i2.028, i64 %i1.029\n"
+      "  store i64 %add, i64* %arrayidx11, align 8\n"
+      "  br label %for.inc\n"
+      "for.inc:                                          \n"
+      "  %inc = add nuw nsw i64 %i2.028, 1\n"
+      "  %exitcond = icmp eq i64 %inc, 8\n"
+      "  br i1 %exitcond, label %for.inc13, label %for.body3\n"
+      "for.inc13:                                        \n"
+      "  %inc14 = add nuw nsw i64 %i1.029, 1\n"
+      "  %exitcond30 = icmp eq i64 %inc14, 8\n"
+      "  br i1 %exitcond30, label %for.end15, label %for.cond1.preheader\n"
+      "for.end15:                                        \n"
+      "  ret void\n"
+      "}\n";
+
+  Module &M = parseModule(ModuleString);
+
+  Function *F = M.getFunction("f");
+  BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor();
+  auto Plan = buildHCFG(LoopHeader);
+
+  VPRegionBlock *TopRegion = cast<VPRegionBlock>(Plan->getEntry());
+  VPBlockBase *PH = TopRegion->getEntry();
+  VPBlockBase *H = PH->getSingleSuccessor();
+  VPBlockBase *InnerLoopH = H->getSingleSuccessor();
+  VPBlockBase *OuterIf = InnerLoopH->getSuccessors()[0];
+  VPBlockBase *InnerLoopLatch = InnerLoopH->getSuccessors()[1];
+  VPBlockBase *InnerIf = OuterIf->getSuccessors()[0];
+  VPValue *CBV1 = InnerLoopH->getCondBit();
+  VPValue *CBV2 = OuterIf->getCondBit();
+
+  // Apply predication.
+  VPlanPredicator VPP(*Plan);
+  VPP.predicate();
+
+  VPBlockBase *InnerLoopLinSucc = InnerLoopH->getSingleSuccessor();
+  VPBlockBase *OuterIfLinSucc = OuterIf->getSingleSuccessor();
+  VPBlockBase *InnerIfLinSucc = InnerIf->getSingleSuccessor();
+  VPValue *OuterIfPred = OuterIf->getPredicate();
+  VPInstruction *InnerAnd =
+      cast<VPInstruction>(InnerIf->getEntryBasicBlock()->begin());
+  VPValue *InnerIfPred = InnerIf->getPredicate();
+
+  // Test block predicates
+  EXPECT_NE(nullptr, CBV1);
+  EXPECT_NE(nullptr, CBV2);
+  EXPECT_NE(nullptr, InnerAnd);
+  EXPECT_EQ(CBV1, OuterIfPred);
+  EXPECT_EQ(InnerAnd->getOpcode(), Instruction::And);
+  EXPECT_EQ(InnerAnd->getOperand(0), CBV1);
+  EXPECT_EQ(InnerAnd->getOperand(1), CBV2);
+  EXPECT_EQ(InnerIfPred, InnerAnd);
+
+  // Test Linearization
+  EXPECT_EQ(InnerLoopLinSucc, OuterIf);
+  EXPECT_EQ(OuterIfLinSucc, InnerIf);
+  EXPECT_EQ(InnerIfLinSucc, InnerLoopLatch);
+}
+
+// Test generation of Not and Or during predication.
+TEST_F(VPlanPredicatorTest, PredicatorNegOrTest) {
+  const char *ModuleString =
+      "@arr = common global [100 x [100 x i32]] zeroinitializer, align 16\n"
+      "@arr2 = common global [100 x [100 x i32]] zeroinitializer, align 16\n"
+      "@arr3 = common global [100 x [100 x i32]] zeroinitializer, align 16\n"
+      "define void @foo() {\n"
+      "entry:\n"
+      "  br label %for.cond1.preheader\n"
+      "for.cond1.preheader:                              \n"
+      "  %indvars.iv42 = phi i64 [ 0, %entry ], [ %indvars.iv.next43, "
+      "%for.inc22 ]\n"
+      "  br label %for.body3\n"
+      "for.body3:                                        \n"
+      "  %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ "
+      "%indvars.iv.next, %if.end21 ]\n"
+      "  %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 "
+      "x i32]]* @arr, i64 0, i64 %indvars.iv, i64 %indvars.iv42\n"
+      "  %0 = load i32, i32* %arrayidx5, align 4\n"
+      "  %cmp6 = icmp slt i32 %0, 100\n"
+      "  br i1 %cmp6, label %if.then, label %if.end21\n"
+      "if.then:                                          \n"
+      "  %cmp7 = icmp sgt i32 %0, 10\n"
+      "  br i1 %cmp7, label %if.then8, label %if.else\n"
+      "if.then8:                                         \n"
+      "  %add = add nsw i32 %0, 10\n"
+      "  %arrayidx12 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 "
+      "x i32]]* @arr2, i64 0, i64 %indvars.iv, i64 %indvars.iv42\n"
+      "  store i32 %add, i32* %arrayidx12, align 4\n"
+      "  br label %if.end\n"
+      "if.else:                                          \n"
+      "  %sub = add nsw i32 %0, -10\n"
+      "  %arrayidx16 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 "
+      "x i32]]* @arr3, i64 0, i64 %indvars.iv, i64 %indvars.iv42\n"
+      "  store i32 %sub, i32* %arrayidx16, align 4\n"
+      "  br label %if.end\n"
+      "if.end:                                           \n"
+      "  store i32 222, i32* %arrayidx5, align 4\n"
+      "  br label %if.end21\n"
+      "if.end21:                                         \n"
+      "  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1\n"
+      "  %exitcond = icmp eq i64 %indvars.iv.next, 100\n"
+      "  br i1 %exitcond, label %for.inc22, label %for.body3\n"
+      "for.inc22:                                        \n"
+      "  %indvars.iv.next43 = add nuw nsw i64 %indvars.iv42, 1\n"
+      "  %exitcond44 = icmp eq i64 %indvars.iv.next43, 100\n"
+      "  br i1 %exitcond44, label %for.end24, label %for.cond1.preheader\n"
+      "for.end24:                                        \n"
+      "  ret void\n"
+      "}\n";
+
+  Module &M = parseModule(ModuleString);
+  Function *F = M.getFunction("foo");
+  BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor();
+  auto Plan = buildHCFG(LoopHeader);
+
+  VPRegionBlock *TopRegion = cast<VPRegionBlock>(Plan->getEntry());
+  VPBlockBase *PH = TopRegion->getEntry();
+  VPBlockBase *H = PH->getSingleSuccessor();
+  VPBlockBase *OuterIfCmpBlk = H->getSingleSuccessor();
+  VPBlockBase *InnerIfCmpBlk = OuterIfCmpBlk->getSuccessors()[0];
+  VPBlockBase *InnerIfTSucc = InnerIfCmpBlk->getSuccessors()[0];
+  VPBlockBase *InnerIfFSucc = InnerIfCmpBlk->getSuccessors()[1];
+  VPBlockBase *TSuccSucc = InnerIfTSucc->getSingleSuccessor();
+  VPBlockBase *FSuccSucc = InnerIfFSucc->getSingleSuccessor();
+
+  VPValue *OuterCBV = OuterIfCmpBlk->getCondBit();
+  VPValue *InnerCBV = InnerIfCmpBlk->getCondBit();
+
+  // Apply predication.
+  VPlanPredicator VPP(*Plan);
+  VPP.predicate();
+
+  VPInstruction *And =
+      cast<VPInstruction>(InnerIfTSucc->getEntryBasicBlock()->begin());
+  VPInstruction *Not =
+      cast<VPInstruction>(InnerIfFSucc->getEntryBasicBlock()->begin());
+  VPInstruction *NotAnd = cast<VPInstruction>(
+      &*std::next(InnerIfFSucc->getEntryBasicBlock()->begin(), 1));
+  VPInstruction *Or =
+      cast<VPInstruction>(TSuccSucc->getEntryBasicBlock()->begin());
+
+  // Test block predicates
+  EXPECT_NE(nullptr, OuterCBV);
+  EXPECT_NE(nullptr, InnerCBV);
+  EXPECT_NE(nullptr, And);
+  EXPECT_NE(nullptr, Not);
+  EXPECT_NE(nullptr, NotAnd);
+
+  EXPECT_EQ(And->getOpcode(), Instruction::And);
+  EXPECT_EQ(NotAnd->getOpcode(), Instruction::And);
+  EXPECT_EQ(Not->getOpcode(), VPInstruction::Not);
+
+  EXPECT_EQ(And->getOperand(0), OuterCBV);
+  EXPECT_EQ(And->getOperand(1), InnerCBV);
+
+  EXPECT_EQ(Not->getOperand(0), InnerCBV);
+
+  EXPECT_EQ(NotAnd->getOperand(0), OuterCBV);
+  EXPECT_EQ(NotAnd->getOperand(1), Not);
+
+  EXPECT_EQ(InnerIfTSucc->getPredicate(), And);
+  EXPECT_EQ(InnerIfFSucc->getPredicate(), NotAnd);
+
+  EXPECT_EQ(TSuccSucc, FSuccSucc);
+  EXPECT_EQ(Or->getOpcode(), Instruction::Or);
+  EXPECT_EQ(TSuccSucc->getPredicate(), Or);
+
+  // Test operands of the Or - account for differences in predecessor block
+  // ordering.
+  VPInstruction *OrOp0Inst = cast<VPInstruction>(Or->getOperand(0));
+  VPInstruction *OrOp1Inst = cast<VPInstruction>(Or->getOperand(1));
+
+  bool ValidOrOperands = false;
+  if (((OrOp0Inst == And) && (OrOp1Inst == NotAnd)) ||
+      ((OrOp0Inst == NotAnd) && (OrOp1Inst == And)))
+    ValidOrOperands = true;
+
+  EXPECT_TRUE(ValidOrOperands);
+}
+
+} // namespace
+} // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp
index 0381925..403ffb1 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanSlpTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Transforms/Vectorize/VPlanSlpTest.cpp ---------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index 67712a7..90f79a3 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -1,10 +1,9 @@
 //===- llvm/unittests/Transforms/Vectorize/VPlanTest.cpp - VPlan tests ----===//
 //
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
index 0fc4a9a..3ee811a 100644
--- a/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
+++ b/src/llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
@@ -1,9 +1,8 @@
 //===- llvm/unittest/Transforms/Vectorize/VPlanTestBase.h -----------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 /// \file
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp
index 558840b..f2fab2f 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRBlockIndexerTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/XRay/FDRTraceWriterTest.cpp ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/XRay/BlockIndexer.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp
index a6e0a8c..5af2745 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/XRay/FDRBlockVerifierTest.cpp --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/Testing/Support/Error.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp
index 03fabdf..bbc15be 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRProducerConsumerTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/XRay/FDRProducerConsumerTest.cpp -----------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp
index a0ec3f2..39c1e86 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRRecordPrinterTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/XRay/FDRRecordPrinterTest.cpp --------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/Support/raw_ostream.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp
index 86b478a..aac3c86 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRRecordsTest.cpp
@@ -1,9 +1,8 @@
 //===- FDRRecords.cpp - Unit Tests for XRay FDR Record Loading ------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "gmock/gmock.h"
diff --git a/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp b/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp
index e78b71d..4f2f06e4 100644
--- a/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/FDRTraceWriterTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/XRay/FDRTraceWriterTest.cpp ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 //
diff --git a/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp b/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp
index b17858f..3c82d53 100644
--- a/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/GraphTest.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittest/XRay/GraphTest.cpp - XRay Graph unit tests -*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp b/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp
index 8486b7b..7eb848f 100644
--- a/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp
+++ b/src/llvm-project/llvm/unittests/XRay/ProfileTest.cpp
@@ -1,9 +1,8 @@
 //===- ProfileTest.cpp - XRay Profile unit tests ----------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 #include "llvm/XRay/Profile.h"
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
index 05880fc..e38ac92 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -52,8 +51,8 @@
 
   // Expose this method publicly for testing.
   void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
-                            uint64_t SectionAddress) {
-    FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
+                            object::SectionedAddress Address) {
+    FileAnalysis::parseSectionContents(SectionBytes, Address);
   }
 
   Error initialiseDisassemblyMembers() {
@@ -107,7 +106,7 @@
           0x41, 0x0e,                   // 21: rex.B (bad)
           0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
 
   EXPECT_EQ(nullptr, Analysis.getInstruction(0x0));
   EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000));
@@ -211,7 +210,7 @@
           0x2f, // 1: (bad)
           0x90  // 2: nop
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
   const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1);
   const auto *GoodInstrMeta =
       Analysis.getPrevInstructionSequential(BadInstrMeta);
@@ -241,7 +240,7 @@
           0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
           0x0f, 0x0b                    // 28: ud2
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
 
   EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF)));
   EXPECT_FALSE(
@@ -276,7 +275,7 @@
           0x75, 0x00,                   // 17: jne +0
           0xc3,                         // 19: retq
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
 
   EXPECT_TRUE(
       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF)));
@@ -323,7 +322,7 @@
           0xeb, 0xdd,                   // 36: jmp 3 [-35]
           0xeb, 0xdc,                   // 38: jmp 4 [-36]
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
 
   const auto *Current = Analysis.getInstruction(0xDEADBEEF);
   const auto *Next = Analysis.getDefiniteNextInstruction(*Current);
@@ -413,7 +412,7 @@
           0xeb, 0xdd,                   // 36: jmp 3 [-35]
           0xeb, 0xdc,                   // 38: jmp 4 [-36]
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
   const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF);
   std::set<const Instr *> XRefs =
       Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
@@ -504,17 +503,18 @@
           0x0f, 0x0b, // 1: ud2
           0x75, 0x00, // 3: jne 5 [+0]
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
             Analysis.validateCFIProtection(Result));
-  Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
+  Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
             Analysis.validateCFIProtection(Result));
-  Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+  Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
             Analysis.validateCFIProtection(Result));
-  Result = GraphBuilder::buildFlowGraph(Analysis, 0x12345678);
+  Result = GraphBuilder::buildFlowGraph(Analysis, {0x12345678, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION,
             Analysis.validateCFIProtection(Result));
 }
@@ -528,8 +528,9 @@
           0x0f, 0x0b, // 2: ud2
           0xff, 0x10, // 4: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -543,8 +544,9 @@
           0xff, 0x10, // 2: callq *(%rax)
           0x0f, 0x0b, // 4: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -561,8 +563,9 @@
           0x75, 0xf9, // 7: jne 2 [-7]
           0x0f, 0x0b, // 9: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -578,8 +581,9 @@
           0x75, 0xfb, // 5: jne 2 [-5]
           0x0f, 0x0b, // 7: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -597,12 +601,13 @@
           0xff, 0x10, // 6: callq *(%rax)
           0x0f, 0x0b, // 8: ud2
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
   uint64_t PrevSearchLengthForConditionalBranch =
       SearchLengthForConditionalBranch;
   SearchLengthForConditionalBranch = 2;
 
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
             Analysis.validateCFIProtection(Result));
 
@@ -622,11 +627,12 @@
           0x90,       // 7: nop
           0x0f, 0x0b, // 8: ud2
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
   SearchLengthForUndef = 2;
 
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
             Analysis.validateCFIProtection(Result));
 
@@ -643,8 +649,9 @@
           0xff, 0x10, // 4: callq *(%rax)
           0x0f, 0x0b, // 6: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
             Analysis.validateCFIProtection(Result));
 }
@@ -659,8 +666,9 @@
           0xff, 0x10, // 4: callq *(%rax)
           0x0f, 0x0b, // 6: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -686,10 +694,11 @@
           0x90,                         // 21: nop
           0x0f, 0x0b,                   // 22: ud2
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
   SearchLengthForUndef = 5;
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
             Analysis.validateCFIProtection(Result));
   SearchLengthForUndef = PrevSearchLengthForUndef;
@@ -705,10 +714,10 @@
           0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130
           0x0f, 0x0b,                   // 0x688127: ud2
       },
-      0x688118);
+      {0x688118, 0x0});
   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
   SearchLengthForUndef = 1;
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x68811d);
+  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x68811d, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
   SearchLengthForUndef = PrevSearchLengthForUndef;
@@ -720,7 +729,7 @@
           0x74, 0x73,                         // 0x7759eb: je 0x775a60
           0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e
       },
-      0x7759eb);
+      {0x7759eb, 0x0});
 
   Analysis.parseSectionContents(
       {
@@ -730,24 +739,24 @@
           0x48, 0x89, 0xde,             // 0x775a65: mov    %rbx,%rsi
           0xff, 0xd1,                   // 0x775a68: callq  *%rcx
       },
-      0x775a56);
+      {0x775a56, 0x0});
 
   Analysis.parseSectionContents(
       {
           0x0f, 0x0b, // 0x775e0e: ud2
       },
-      0x775e0e);
+      {0x775e0e, 0x0});
   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
   SearchLengthForUndef = 1;
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
+  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
             Analysis.validateCFIProtection(Result));
   SearchLengthForUndef = 2;
-  Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
+  Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
   SearchLengthForUndef = 3;
-  Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
+  Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
   SearchLengthForUndef = PrevSearchLengthForUndef;
@@ -763,8 +772,9 @@
           0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax
           0xff, 0x10,                         // 10: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 10);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 10, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -779,8 +789,9 @@
           0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax
           0xff, 0x10,             // 8: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -795,8 +806,9 @@
           0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax
           0xff, 0x10,                   // 9: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -813,8 +825,9 @@
           0x75, 0xf9, // 8: jne 2 [-7]
           0x0f, 0x0b, // 10: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -826,8 +839,9 @@
       {
           0x00, 0x01, 0x3f, 0xd6, // 0: blr x8
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
             Analysis.validateCFIProtection(Result));
 }
@@ -841,8 +855,9 @@
           0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
           0x00, 0x01, 0x3f, 0xd6, // 8: blr x8
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -857,8 +872,9 @@
           0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1
           0x00, 0x01, 0x3f, 0xd6, // 12: blr x8
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -873,8 +889,9 @@
           0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
           0x20, 0x00, 0x1f, 0xd6, // 12: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -890,8 +907,9 @@
           0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
           0x20, 0x00, 0x1f, 0xd6, // 16: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -907,8 +925,9 @@
           0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1
           0x20, 0x00, 0x1f, 0xd6, // 16: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -924,8 +943,9 @@
           0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
           0x20, 0x00, 0x1f, 0xd6, // 16: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -941,8 +961,9 @@
           0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16]
           0x20, 0x00, 0x1f, 0xd6, // 16: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -958,8 +979,9 @@
           0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
           0x20, 0x00, 0x1f, 0xd6, // 16: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -975,8 +997,9 @@
           0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16]
           0x20, 0x00, 0x1f, 0xd6, // 16: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -991,8 +1014,9 @@
           0x20, 0x00, 0x20, 0xd4, // 8: brk #0x1
           0x20, 0x00, 0x1f, 0xd6, // 12: br x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
             Analysis.validateCFIProtection(Result));
 }
@@ -1010,8 +1034,9 @@
           0x20, 0x00, 0x1f, 0xd6, // 20: br x1
           0x20, 0x00, 0x20, 0xd4, // 24: brk #0x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 20);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 20, 0x0});
   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
             Analysis.validateCFIProtection(Result));
 }
@@ -1030,8 +1055,9 @@
           0x20, 0x00, 0x1f, 0xd6, // 24: br x1
           0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
@@ -1050,8 +1076,9 @@
           0x20, 0x00, 0x1f, 0xd6, // 24: br x1
           0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
             Analysis.validateCFIProtection(Result));
 }
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
index a7d09b5..a57958d 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-cfi-verify/GraphBuilder.cpp
@@ -1,9 +1,8 @@
 //===- llvm/unittests/llvm-cfi-verify/GraphBuilder.cpp --------------===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -114,8 +113,8 @@
 
   // Expose this method publicly for testing.
   void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
-                            uint64_t SectionAddress) {
-    FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
+                            object::SectionedAddress Address) {
+    FileAnalysis::parseSectionContents(SectionBytes, Address);
   }
 
   Error initialiseDisassemblyMembers() {
@@ -157,8 +156,9 @@
           0x0f, 0x0b, // 2: ud2
           0xff, 0x10, // 4: callq *(%rax)
       },
-      0xDEADBEEF);
-  const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+      {0xDEADBEEF, 0x0});
+  const auto Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
 
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
@@ -183,8 +183,9 @@
           0xff, 0x10, // 2: callq *(%rax)
           0x0f, 0x0b, // 4: ud2
       },
-      0xDEADBEEF);
-  const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+      {0xDEADBEEF, 0x0});
+  const auto Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
 
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
@@ -212,8 +213,9 @@
           0x75, 0xf9, // 7: jne 2 [-7]
           0x0f, 0x0b, // 9: ud2
       },
-      0xDEADBEEF);
-  const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+      {0xDEADBEEF, 0x0});
+  const auto Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
 
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
@@ -250,8 +252,9 @@
           0x75, 0xfb, // 5: jne 2 [-5]
           0x0f, 0x0b, // 7: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
 
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
@@ -285,16 +288,17 @@
           0x90,       // 0: nop
           0x75, 0xfe, // 1: jne 1 [-2]
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
 
-  Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
+  Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
 
-  Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADC0DE);
+  Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADC0DE, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
 }
@@ -307,8 +311,9 @@
           0xeb, 0xfe, // 0: jmp 0 [-2]
           0xff, 0x10, // 2: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
   EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
   EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 2));
   EXPECT_THAT(Result.IntermediateNodes, IsEmpty());
@@ -322,8 +327,9 @@
           0x75, 0xfe, // 0: jne 0 [-2]
           0xff, 0x10, // 2: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
   EXPECT_THAT(
@@ -345,8 +351,9 @@
           0xeb, 0xfc, // 2: jmp 0 [-4]
           0xff, 0x10, // 4: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
   EXPECT_THAT(
@@ -369,8 +376,9 @@
           0xeb, 0xfc, // 2: jmp 0 [-4]
           0xff, 0x10, // 4: callq *(%rax)
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 4));
   EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
 }
@@ -388,12 +396,13 @@
           0xff, 0x10, // 6: callq *(%rax)
           0x0f, 0x0b, // 8: ud2
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
   uint64_t PrevSearchLengthForConditionalBranch =
       SearchLengthForConditionalBranch;
   SearchLengthForConditionalBranch = 2;
 
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
   EXPECT_THAT(Result.OrphanedNodes,
               Each(HasPath(Result, ElementsAre(0xDEADBEEF + 4, 0xDEADBEEF + 5,
@@ -417,11 +426,12 @@
           0x90,       // 7: nop
           0x0f, 0x0b, // 8: ud2
       },
-      0xDEADBEEF);
+      {0xDEADBEEF, 0x0});
   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
   SearchLengthForUndef = 2;
 
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(
       Result.ConditionalBranchNodes,
@@ -451,8 +461,9 @@
           0x75, 0xfb, // 5: jne 2 [-5]
           0x0f, 0x0b, // 7: ud2
       },
-      0xDEADBEEF);
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
+      {0xDEADBEEF, 0x0});
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
   EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
   EXPECT_THAT(
@@ -530,11 +541,12 @@
           0x90,                         // 21: nop
           0x0f, 0x0b,                   // 22: ud2
       },
-      0x1000);
+      {0x1000, 0x0});
   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
   SearchLengthForUndef = 5;
 
-  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x1000 + 9);
+  GraphResult Result =
+      GraphBuilder::buildFlowGraph(Analysis, {0x1000 + 9, 0x0});
 
   EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
   EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(3));
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
index 6dd5305..4a68541 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/AArch64/TargetTest.cpp
@@ -1,9 +1,8 @@
 //===-- TargetTest.cpp ------------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp
index a20fa55..70ad487 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ARM/AssemblerTest.cpp
@@ -1,9 +1,8 @@
 //===-- AssemblerTest.cpp ---------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp
index c518491..9414a48 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/BenchmarkRunnerTest.cpp
@@ -1,9 +1,8 @@
 //===-- BenchmarkRunnerTest.cpp ---------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp
index 8ea77dc..b23938a 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp
@@ -1,9 +1,8 @@
 //===-- ClusteringTest.cpp --------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -23,6 +22,11 @@
 using testing::UnorderedElementsAre;
 using testing::UnorderedElementsAreArray;
 
+static const auto HasPoints = [](const std::vector<int> &Indices) {
+  return Field(&InstructionBenchmarkClustering::Cluster::PointIndices,
+                 UnorderedElementsAreArray(Indices));
+};
+
 TEST(ClusteringTest, Clusters3D) {
   std::vector<InstructionBenchmark> Points(6);
 
@@ -42,12 +46,8 @@
   // Error cluster: points {2}
   Points[2].Error = "oops";
 
-  auto HasPoints = [](const std::vector<int> &Indices) {
-    return Field(&InstructionBenchmarkClustering::Cluster::PointIndices,
-                 UnorderedElementsAreArray(Indices));
-  };
-
-  auto Clustering = InstructionBenchmarkClustering::create(Points, 2, 0.25);
+  auto Clustering = InstructionBenchmarkClustering::create(
+      Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25);
   ASSERT_TRUE((bool)Clustering);
   EXPECT_THAT(Clustering.get().getValidClusters(),
               UnorderedElementsAre(HasPoints({0, 3}), HasPoints({1, 4})));
@@ -74,7 +74,9 @@
       {"x", 0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
   Points[1].Measurements = {{"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
   auto Error =
-      InstructionBenchmarkClustering::create(Points, 2, 0.25).takeError();
+      InstructionBenchmarkClustering::create(
+          Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25)
+          .takeError();
   ASSERT_TRUE((bool)Error);
   consumeError(std::move(Error));
 }
@@ -84,7 +86,9 @@
   Points[0].Measurements = {{"x", 0.01, 0.0}, {"y", 1.02, 0.0}};
   Points[1].Measurements = {{"y", 1.02, 0.0}, {"x", 1.98, 0.0}};
   auto Error =
-      InstructionBenchmarkClustering::create(Points, 2, 0.25).takeError();
+      InstructionBenchmarkClustering::create(
+          Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25)
+          .takeError();
   ASSERT_TRUE((bool)Error);
   consumeError(std::move(Error));
 }
@@ -103,6 +107,40 @@
             InstructionBenchmarkClustering::ClusterId::error());
 }
 
+TEST(ClusteringTest, Ordering1) {
+  std::vector<InstructionBenchmark> Points(3);
+
+  Points[0].Measurements = {
+      {"x", 0.0, 0.0}};
+  Points[1].Measurements = {
+      {"x", 1.0, 0.0}};
+  Points[2].Measurements = {
+      {"x", 2.0, 0.0}};
+
+  auto Clustering = InstructionBenchmarkClustering::create(
+      Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 1.1);
+  ASSERT_TRUE((bool)Clustering);
+  EXPECT_THAT(Clustering.get().getValidClusters(),
+              UnorderedElementsAre(HasPoints({0, 1, 2})));
+}
+
+TEST(ClusteringTest, Ordering2) {
+  std::vector<InstructionBenchmark> Points(3);
+
+  Points[0].Measurements = {
+      {"x", 0.0, 0.0}};
+  Points[1].Measurements = {
+      {"x", 2.0, 0.0}};
+  Points[2].Measurements = {
+      {"x", 1.0, 0.0}};
+
+  auto Clustering = InstructionBenchmarkClustering::create(
+      Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 1.1);
+  ASSERT_TRUE((bool)Clustering);
+  EXPECT_THAT(Clustering.get().getValidClusters(),
+              UnorderedElementsAre(HasPoints({0, 1, 2})));
+}
+
 } // namespace
 } // namespace exegesis
 } // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
index 8a144e5..fcbff94 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/Common/AssemblerUtils.h
@@ -1,9 +1,8 @@
 //===-- AssemblerUtils.h ----------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp
index 91ed4a6..39942af 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PerfHelperTest.cpp
@@ -1,9 +1,8 @@
 //===-- PerfHelperTest.cpp --------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp
index 15d81ca..a7d2c6d 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/AnalysisTest.cpp
@@ -1,9 +1,8 @@
 //===-- AnalysisTest.cpp ---------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp
index 0e34a15..3f6c5b6d 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/PowerPC/TargetTest.cpp
@@ -1,9 +1,8 @@
 //===-- TargetTest.cpp ---------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp
index 8453720..a7c8ba6 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/RegisterValueTest.cpp
@@ -1,9 +1,8 @@
 //===-- RegisterValueTest.cpp -----------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp
index 451c3f6..ce7d9be 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AssemblerTest.cpp
@@ -1,9 +1,8 @@
 //===-- AssemblerTest.cpp ---------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp
index f069c21..56cbe31 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/BenchmarkResultTest.cpp
@@ -1,9 +1,8 @@
 //===-- BenchmarkResultTest.cpp ---------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt
index 5078e7b..88c38d0 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/CMakeLists.txt
@@ -15,10 +15,10 @@
 
 add_llvm_unittest(LLVMExegesisX86Tests
   AssemblerTest.cpp
-  AnalysisTest.cpp
   BenchmarkResultTest.cpp
-  SnippetGeneratorTest.cpp
   RegisterAliasingTest.cpp
+  SchedClassResolutionTest.cpp
+  SnippetGeneratorTest.cpp
   TargetTest.cpp
   )
 target_link_libraries(LLVMExegesisX86Tests PRIVATE
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp
index c85c99c2..b65b2a9 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/RegisterAliasingTest.cpp
@@ -1,9 +1,8 @@
 //===-- RegisterAliasingTest.cpp --------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AnalysisTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp
similarity index 79%
rename from src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AnalysisTest.cpp
rename to src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp
index c893918..9e74546 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/AnalysisTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SchedClassResolutionTest.cpp
@@ -1,13 +1,12 @@
-//===-- AnalysisTest.cpp ---------------------------------------*- C++ -*-===//
+//===-- SchedClassResolutionTest.cpp ----------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
-#include "Analysis.h"
+#include "SchedClassResolution.h"
 
 #include <cassert>
 #include <memory>
@@ -24,9 +23,9 @@
 using testing::Pair;
 using testing::UnorderedElementsAre;
 
-class AnalysisTest : public ::testing::Test {
+class SchedClassResolutionTest : public ::testing::Test {
 protected:
-  AnalysisTest() {
+  SchedClassResolutionTest() {
     const std::string TT = "x86_64-unknown-linux";
     std::string error;
     const llvm::Target *const TheTarget =
@@ -79,20 +78,20 @@
   uint16_t P0156Idx = 0;
 };
 
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_2P0) {
+TEST_F(SchedClassResolutionTest, ComputeIdealizedProcResPressure_2P0) {
   const auto Pressure =
       computeIdealizedProcResPressure(STI->getSchedModel(), {{P0Idx, 2}});
   EXPECT_THAT(Pressure, UnorderedElementsAre(Pair(P0Idx, 2.0)));
 }
 
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_2P05) {
+TEST_F(SchedClassResolutionTest, ComputeIdealizedProcResPressure_2P05) {
   const auto Pressure =
       computeIdealizedProcResPressure(STI->getSchedModel(), {{P05Idx, 2}});
   EXPECT_THAT(Pressure,
               UnorderedElementsAre(Pair(P0Idx, 1.0), Pair(P5Idx, 1.0)));
 }
 
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_2P05_2P0156) {
+TEST_F(SchedClassResolutionTest, ComputeIdealizedProcResPressure_2P05_2P0156) {
   const auto Pressure = computeIdealizedProcResPressure(
       STI->getSchedModel(), {{P05Idx, 2}, {P0156Idx, 2}});
   EXPECT_THAT(Pressure,
@@ -100,7 +99,8 @@
                                    Pair(P5Idx, 1.0), Pair(P6Idx, 1.0)));
 }
 
-TEST_F(AnalysisTest, ComputeIdealizedProcResPressure_1P1_1P05_2P0156) {
+TEST_F(SchedClassResolutionTest,
+       ComputeIdealizedProcResPressure_1P1_1P05_2P0156) {
   const auto Pressure = computeIdealizedProcResPressure(
       STI->getSchedModel(), {{P1Idx, 1}, {P05Idx, 1}, {P0156Idx, 2}});
   EXPECT_THAT(Pressure,
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
index 1689def..8b110f8 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/SnippetGeneratorTest.cpp
@@ -1,9 +1,8 @@
 //===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -228,19 +227,20 @@
 }
 
 TEST_F(UopsSnippetGeneratorTest, StaticRenaming) {
-  // CMOVA32rr has tied variables, we enumerate the possible values to execute
+  // CMOV32rr has tied variables, we enumerate the possible values to execute
   // as many in parallel as possible.
 
-  // - CMOVA32rr
+  // - CMOV32rr
   // - Op0 Explicit Def RegClass(GR32)
   // - Op1 Explicit Use RegClass(GR32) TiedToOp0
   // - Op2 Explicit Use RegClass(GR32)
+  // - Op3 Explicit Use Immediate
   // - Op3 Implicit Use Reg(EFLAGS)
   // - Var0 [Op0,Op1]
   // - Var1 [Op2]
   // - hasTiedRegisters (execution is always serial)
   // - hasAliasingRegisters
-  const unsigned Opcode = llvm::X86::CMOVA32rr;
+  const unsigned Opcode = llvm::X86::CMOV32rr;
   const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
   ASSERT_THAT(CodeTemplates, SizeIs(1));
   const auto &CT = CodeTemplates[0];
@@ -250,7 +250,7 @@
   ASSERT_THAT(CT.Instructions, SizeIs(kInstructionCount));
   std::unordered_set<unsigned> AllDefRegisters;
   for (const auto &IT : CT.Instructions) {
-    ASSERT_THAT(IT.VariableValues, SizeIs(2));
+    ASSERT_THAT(IT.VariableValues, SizeIs(3));
     AllDefRegisters.insert(IT.VariableValues[0].getReg());
   }
   EXPECT_THAT(AllDefRegisters, SizeIs(kInstructionCount))
diff --git a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
index b1ccb48..344ec60 100644
--- a/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
+++ b/src/llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp
@@ -1,9 +1,8 @@
 //===-- TargetTest.cpp -----------------------------------------*- C++ -*-===//
 //
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
 
@@ -145,6 +144,10 @@
   Core2Avx512TargetTest() : X86TargetTest("+avx512vl") {}
 };
 
+TEST_F(Core2TargetTest, NoHighByteRegs) {
+  EXPECT_TRUE(State.getRATC().reservedRegisters().test(X86::AH));
+}
+
 TEST_F(Core2TargetTest, SetFlags) {
   const unsigned Reg = llvm::X86::EFLAGS;
   EXPECT_THAT(