diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index c53cbd2..a1610c9 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -1011,6 +1011,16 @@
   return H::combine_contiguous(std::move(h), a.data(), a.size());
 }
 
+template <typename T, size_t N, typename A, typename Predicate>
+constexpr typename InlinedVector<T, N, A>::size_type erase_if(
+    InlinedVector<T, N, A>& v, Predicate pred) {
+  const auto it = std::remove_if(v.begin(), v.end(), std::move(pred));
+  const auto removed = static_cast<typename InlinedVector<T, N, A>::size_type>(
+      std::distance(it, v.end()));
+  v.erase(it, v.end());
+  return removed;
+}
+
 ABSL_NAMESPACE_END
 }  // namespace absl
 
diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc
index ff0e77b..ba8c4a8 100644
--- a/absl/container/inlined_vector_test.cc
+++ b/absl/container/inlined_vector_test.cc
@@ -51,6 +51,7 @@
 using testing::Each;
 using testing::ElementsAre;
 using testing::ElementsAreArray;
+using testing::IsEmpty;
 using testing::Eq;
 using testing::Gt;
 using testing::Pointee;
@@ -2254,4 +2255,22 @@
             sizeof(MySpan<int>) / sizeof(int));
 }
 
+TEST(IntVec, EraseIf) {
+  IntVec v = {3, 1, 2, 0};
+  EXPECT_EQ(absl::erase_if(v, [](int i) { return i > 1; }), 2u);
+  EXPECT_THAT(v, ElementsAre(1, 0));
+}
+
+TEST(IntVec, EraseIfMatchesNone) {
+  IntVec v = {1, 2, 3};
+  EXPECT_EQ(absl::erase_if(v, [](int i) { return i > 10; }), 0u);;
+  EXPECT_THAT(v, ElementsAre(1, 2, 3));
+}
+
+TEST(IntVec, EraseIfMatchesAll) {
+  IntVec v = {1, 2, 3};
+  EXPECT_EQ(absl::erase_if(v, [](int i) { return i > 0; }), 3u);
+  EXPECT_THAT(v, IsEmpty());
+}
+
 }  // anonymous namespace
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 679d68c..533886f 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -1175,30 +1175,32 @@
 }
 
 // General notes on capacity/growth methods below:
-// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
-//   average of two empty slots per group.
-// - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity.
+// - We use 27/32 as maximum load factor. For 16-wide groups, that gives an
+//   average of 2.5 empty slots per group.
 // - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we
 //   never need to probe (the whole table fits in one group) so we don't need a
 //   load factor less than 1.
+// - For (capacity+1) == Group::kWidth, growth is capacity - 1 since we need
+//   at least one empty slot for probing algorithm.
+// - For (capacity+1) > Group::kWidth, growth is 27/32*capacity.
 
 // Given `capacity`, applies the load factor; i.e., it returns the maximum
 // number of values we should put into the table before a resizing rehash.
 constexpr size_t CapacityToGrowth(size_t capacity) {
   ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
-  // `capacity*7/8`
+  // `capacity*27/32`
   if (Group::kWidth == 8 && capacity == 7) {
-    // x-x/8 does not work when x==7.
+    // formula does not work when x==7.
     return 6;
   }
-  return capacity - capacity / 8;
+  return capacity - capacity / 8 - capacity / 32;
 }
 
 // Given `size`, "unapplies" the load factor to find how large the capacity
 // should be to stay within the load factor.
 //
 // For size == 0, returns 0.
-// For other values, returns the same as `NormalizeCapacity(size*8/7)`.
+// For other values, returns the same as `NormalizeCapacity(size*32/27)`.
 constexpr size_t SizeToCapacity(size_t size) {
   if (size == 0) {
     return 0;
@@ -1207,18 +1209,10 @@
   // Shifting right `~size_t{}` by `leading_zeros` yields
   // NormalizeCapacity(size).
   int leading_zeros = absl::countl_zero(size);
-  constexpr size_t kLast3Bits = size_t{7} << (sizeof(size_t) * 8 - 3);
-  // max_size_for_next_capacity = max_load_factor * next_capacity
-  //                            = (7/8) * (~size_t{} >> leading_zeros)
-  //                            = (7/8*~size_t{}) >> leading_zeros
-  //                            = kLast3Bits >> leading_zeros
-  size_t max_size_for_next_capacity = kLast3Bits >> leading_zeros;
+  size_t next_capacity = ~size_t{} >> leading_zeros;
+  size_t max_size_for_next_capacity = CapacityToGrowth(next_capacity);
   // Decrease shift if size is too big for the minimum capacity.
   leading_zeros -= static_cast<int>(size > max_size_for_next_capacity);
-  if constexpr (Group::kWidth == 8) {
-    // Formula doesn't work when size==7 for 8-wide groups.
-    leading_zeros -= (size == 7);
-  }
   return (~size_t{}) >> leading_zeros;
 }
 
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 044e5b5..d411709 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -276,28 +276,53 @@
   EXPECT_EQ(15 * 2 + 1, NormalizeCapacity(15 + 2));
 }
 
-TEST(Util, GrowthAndCapacity) {
-  // Verify that GrowthToCapacity gives the minimum capacity that has enough
-  // growth.
+TEST(Util, SizeToCapacitySmallValues) {
   EXPECT_EQ(SizeToCapacity(0), 0);
   EXPECT_EQ(SizeToCapacity(1), 1);
   EXPECT_EQ(SizeToCapacity(2), 3);
   EXPECT_EQ(SizeToCapacity(3), 3);
+  EXPECT_EQ(SizeToCapacity(4), 7);
+  EXPECT_EQ(SizeToCapacity(5), 7);
+  EXPECT_EQ(SizeToCapacity(6), 7);
+  if (Group::kWidth == 16) {
+    EXPECT_EQ(SizeToCapacity(7), 7);
+    EXPECT_EQ(SizeToCapacity(14), 15);
+  } else {
+    EXPECT_EQ(SizeToCapacity(7), 15);
+  }
+}
+
+TEST(Util, CapacityToGrowthSmallValues) {
+  EXPECT_EQ(CapacityToGrowth(1), 1);
+  EXPECT_EQ(CapacityToGrowth(3), 3);
+  if (Group::kWidth == 16) {
+    EXPECT_EQ(CapacityToGrowth(7), 7);
+  } else {
+    EXPECT_EQ(CapacityToGrowth(7), 6);
+  }
+  EXPECT_EQ(CapacityToGrowth(15), 14);
+  EXPECT_EQ(CapacityToGrowth(31), 28);
+  EXPECT_EQ(CapacityToGrowth(63), 55);
+}
+
+TEST(Util, GrowthAndCapacity) {
+  // Verify that GrowthToCapacity gives the minimum capacity that has enough
+  // growth.
   for (size_t growth = 1; growth < 10000; ++growth) {
     SCOPED_TRACE(growth);
     size_t capacity = SizeToCapacity(growth);
     ASSERT_TRUE(IsValidCapacity(capacity));
     // The capacity is large enough for `growth`.
-    EXPECT_THAT(CapacityToGrowth(capacity), Ge(growth));
+    ASSERT_THAT(CapacityToGrowth(capacity), Ge(growth));
     // For (capacity+1) < kWidth, growth should equal capacity.
     if (capacity + 1 < Group::kWidth) {
-      EXPECT_THAT(CapacityToGrowth(capacity), Eq(capacity));
+      ASSERT_THAT(CapacityToGrowth(capacity), Eq(capacity));
     } else {
-      EXPECT_THAT(CapacityToGrowth(capacity), Lt(capacity));
+      ASSERT_THAT(CapacityToGrowth(capacity), Lt(capacity));
     }
     if (growth != 0 && capacity > 1) {
       // There is no smaller capacity that works.
-      EXPECT_THAT(CapacityToGrowth(capacity / 2), Lt(growth));
+      ASSERT_THAT(CapacityToGrowth(capacity / 2), Lt(growth)) << capacity;
     }
   }
 
@@ -305,9 +330,9 @@
        capacity = 2 * capacity + 1) {
     SCOPED_TRACE(capacity);
     size_t growth = CapacityToGrowth(capacity);
-    EXPECT_THAT(growth, Lt(capacity));
-    EXPECT_EQ(SizeToCapacity(growth), capacity);
-    EXPECT_EQ(NormalizeCapacity(SizeToCapacity(growth)), capacity);
+    ASSERT_THAT(growth, Lt(capacity));
+    ASSERT_EQ(SizeToCapacity(growth), capacity);
+    ASSERT_EQ(NormalizeCapacity(SizeToCapacity(growth)), capacity);
   }
 }
 
diff --git a/absl/crc/internal/crc_x86_arm_combined.cc b/absl/crc/internal/crc_x86_arm_combined.cc
index 30cf6a1..ebd9c3f 100644
--- a/absl/crc/internal/crc_x86_arm_combined.cc
+++ b/absl/crc/internal/crc_x86_arm_combined.cc
@@ -317,6 +317,46 @@
     return crc;
   }
 
+  // Same as Process64BytesCRC, but just interleaved for 2 streams.
+  ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesCRC2Streams(
+      const uint8_t* p0, const uint8_t* p1, uint64_t* crc) const {
+    uint64_t crc0 = crc[0];
+    uint64_t crc1 = crc[1];
+    for (int i = 0; i < 8; i++) {
+      crc0 = CRC32_u64(static_cast<uint32_t>(crc0),
+                       absl::little_endian::Load64(p0));
+      crc1 = CRC32_u64(static_cast<uint32_t>(crc1),
+                       absl::little_endian::Load64(p1));
+      p0 += 8;
+      p1 += 8;
+    }
+    crc[0] = crc0;
+    crc[1] = crc1;
+  }
+
+  // Same as Process64BytesCRC, but just interleaved for 3 streams.
+  ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesCRC3Streams(
+      const uint8_t* p0, const uint8_t* p1, const uint8_t* p2,
+      uint64_t* crc) const {
+    uint64_t crc0 = crc[0];
+    uint64_t crc1 = crc[1];
+    uint64_t crc2 = crc[2];
+    for (int i = 0; i < 8; i++) {
+      crc0 = CRC32_u64(static_cast<uint32_t>(crc0),
+                       absl::little_endian::Load64(p0));
+      crc1 = CRC32_u64(static_cast<uint32_t>(crc1),
+                       absl::little_endian::Load64(p1));
+      crc2 = CRC32_u64(static_cast<uint32_t>(crc2),
+                       absl::little_endian::Load64(p2));
+      p0 += 8;
+      p1 += 8;
+      p2 += 8;
+    }
+    crc[0] = crc0;
+    crc[1] = crc1;
+    crc[2] = crc2;
+  }
+
   // Constants generated by './scripts/gen-crc-consts.py x86_pclmul
   // crc32_lsb_0x82f63b78' from the Linux kernel.
   alignas(16) static constexpr uint64_t kFoldAcross512Bits[2] = {
@@ -452,9 +492,19 @@
       uint64_t l64_pclmul[kMaxStreams] = {0};
 
       // Peel first iteration, because PCLMULQDQ stream, needs setup.
-      for (size_t i = 0; i < num_crc_streams; i++) {
-        l64_crc[i] = Process64BytesCRC(crc_streams[i], l64_crc[i]);
-        crc_streams[i] += 16 * 4;
+      if (num_crc_streams == 1) {
+        l64_crc[0] = Process64BytesCRC(crc_streams[0], l64_crc[0]);
+        crc_streams[0] += 16 * 4;
+      } else if (num_crc_streams == 2) {
+        Process64BytesCRC2Streams(crc_streams[0], crc_streams[1], l64_crc);
+        crc_streams[0] += 16 * 4;
+        crc_streams[1] += 16 * 4;
+      } else {
+        Process64BytesCRC3Streams(crc_streams[0], crc_streams[1],
+                                  crc_streams[2], l64_crc);
+        crc_streams[0] += 16 * 4;
+        crc_streams[1] += 16 * 4;
+        crc_streams[2] += 16 * 4;
       }
 
       V128 partialCRC[kMaxStreams][4];
@@ -492,24 +542,28 @@
         // }
         // But unrolling and interleaving PCLMULQDQ and CRC blocks manually
         // gives ~2% performance boost.
-        l64_crc[0] = Process64BytesCRC(crc_streams[0], l64_crc[0]);
-        crc_streams[0] += 16 * 4;
+        if (num_crc_streams == 1) {
+          l64_crc[0] = Process64BytesCRC(crc_streams[0], l64_crc[0]);
+          crc_streams[0] += 16 * 4;
+        } else if (num_crc_streams == 2) {
+          Process64BytesCRC2Streams(crc_streams[0], crc_streams[1], l64_crc);
+          crc_streams[0] += 16 * 4;
+          crc_streams[1] += 16 * 4;
+        } else {
+          Process64BytesCRC3Streams(crc_streams[0], crc_streams[1],
+                                    crc_streams[2], l64_crc);
+          crc_streams[0] += 16 * 4;
+          crc_streams[1] += 16 * 4;
+          crc_streams[2] += 16 * 4;
+        }
         if (num_pclmul_streams > 0) {
           Process64BytesPclmul(pclmul_streams[0], partialCRC[0]);
           pclmul_streams[0] += 16 * 4;
         }
-        if (num_crc_streams > 1) {
-          l64_crc[1] = Process64BytesCRC(crc_streams[1], l64_crc[1]);
-          crc_streams[1] += 16 * 4;
-        }
         if (num_pclmul_streams > 1) {
           Process64BytesPclmul(pclmul_streams[1], partialCRC[1]);
           pclmul_streams[1] += 16 * 4;
         }
-        if (num_crc_streams > 2) {
-          l64_crc[2] = Process64BytesCRC(crc_streams[2], l64_crc[2]);
-          crc_streams[2] += 16 * 4;
-        }
         if (num_pclmul_streams > 2) {
           Process64BytesPclmul(pclmul_streams[2], partialCRC[2]);
           pclmul_streams[2] += 16 * 4;
diff --git a/absl/hash/internal/hash.cc b/absl/hash/internal/hash.cc
index a693d5c..9e43e94 100644
--- a/absl/hash/internal/hash.cc
+++ b/absl/hash/internal/hash.cc
@@ -59,8 +59,7 @@
     uint64_t duplicated_state2 = current_state;
 
     do {
-      // Always prefetch the next cacheline.
-      PrefetchToLocalCache(ptr + ABSL_CACHELINE_SIZE);
+      PrefetchToLocalCache(ptr + 5 * ABSL_CACHELINE_SIZE);
 
       uint64_t a = absl::base_internal::UnalignedLoad64(ptr);
       uint64_t b = absl::base_internal::UnalignedLoad64(ptr + 8);
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index ae736b2..775e132 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -609,9 +609,15 @@
 constexpr uint128 operator>>(uint128 lhs, int amount);
 constexpr uint128 operator+(uint128 lhs, uint128 rhs);
 constexpr uint128 operator-(uint128 lhs, uint128 rhs);
+#if defined(ABSL_HAVE_INTRINSIC_INT128)
+constexpr uint128 operator*(uint128 lhs, uint128 rhs);
+constexpr uint128 operator/(uint128 lhs, uint128 rhs);
+constexpr uint128 operator%(uint128 lhs, uint128 rhs);
+#else   // ABSL_HAVE_INTRINSIC_INT128
 uint128 operator*(uint128 lhs, uint128 rhs);
 uint128 operator/(uint128 lhs, uint128 rhs);
 uint128 operator%(uint128 lhs, uint128 rhs);
+#endif  // ABSL_HAVE_INTRINSIC_INT128
 
 inline uint128& uint128::operator<<=(int amount) {
   *this = *this << amount;
@@ -1021,19 +1027,15 @@
 #endif
 }
 
+#if !defined(ABSL_HAVE_INTRINSIC_INT128)
 inline uint128 operator*(uint128 lhs, uint128 rhs) {
-#if defined(ABSL_HAVE_INTRINSIC_INT128)
-  // TODO(strel) Remove once alignment issues are resolved and unsigned __int128
-  // can be used for uint128 storage.
-  return static_cast<unsigned __int128>(lhs) *
-         static_cast<unsigned __int128>(rhs);
-#elif defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
+#if defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
   uint64_t carry;
   uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry);
   return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) +
                          Uint128High64(lhs) * Uint128Low64(rhs) + carry,
                      low);
-#else   // ABSL_HAVE_INTRINSIC128
+#else   // _MSC_VER
   uint64_t a32 = Uint128Low64(lhs) >> 32;
   uint64_t a00 = Uint128Low64(lhs) & 0xffffffff;
   uint64_t b32 = Uint128Low64(rhs) >> 32;
@@ -1045,16 +1047,24 @@
   result += uint128(a32 * b00) << 32;
   result += uint128(a00 * b32) << 32;
   return result;
-#endif  // ABSL_HAVE_INTRINSIC128
+#endif  // _MSC_VER
 }
+#endif  // ABSL_HAVE_INTRINSIC_INT128
 
 #if defined(ABSL_HAVE_INTRINSIC_INT128)
-inline uint128 operator/(uint128 lhs, uint128 rhs) {
+constexpr uint128 operator*(uint128 lhs, uint128 rhs) {
+  // TODO(strel) Remove once alignment issues are resolved and unsigned __int128
+  // can be used for uint128 storage.
+  return static_cast<unsigned __int128>(lhs) *
+         static_cast<unsigned __int128>(rhs);
+}
+
+constexpr uint128 operator/(uint128 lhs, uint128 rhs) {
   return static_cast<unsigned __int128>(lhs) /
          static_cast<unsigned __int128>(rhs);
 }
 
-inline uint128 operator%(uint128 lhs, uint128 rhs) {
+constexpr uint128 operator%(uint128 lhs, uint128 rhs) {
   return static_cast<unsigned __int128>(lhs) %
          static_cast<unsigned __int128>(rhs);
 }
@@ -1112,9 +1122,15 @@
 constexpr int128 operator-(int128 v);
 constexpr int128 operator+(int128 lhs, int128 rhs);
 constexpr int128 operator-(int128 lhs, int128 rhs);
+#if defined(ABSL_HAVE_INTRINSIC_INT128)
+constexpr int128 operator*(int128 lhs, int128 rhs);
+constexpr int128 operator/(int128 lhs, int128 rhs);
+constexpr int128 operator%(int128 lhs, int128 rhs);
+#else
 int128 operator*(int128 lhs, int128 rhs);
 int128 operator/(int128 lhs, int128 rhs);
 int128 operator%(int128 lhs, int128 rhs);
+#endif  // ABSL_HAVE_INTRINSIC_INT128
 constexpr int128 operator|(int128 lhs, int128 rhs);
 constexpr int128 operator&(int128 lhs, int128 rhs);
 constexpr int128 operator^(int128 lhs, int128 rhs);
diff --git a/absl/numeric/int128_have_intrinsic.inc b/absl/numeric/int128_have_intrinsic.inc
index 216115a..62eb045 100644
--- a/absl/numeric/int128_have_intrinsic.inc
+++ b/absl/numeric/int128_have_intrinsic.inc
@@ -254,17 +254,19 @@
   return static_cast<__int128>(lhs) - static_cast<__int128>(rhs);
 }
 
-inline int128 operator*(int128 lhs, int128 rhs) {
+#if defined(ABSL_HAVE_INTRINSIC_INT128)
+constexpr int128 operator*(int128 lhs, int128 rhs) {
   return static_cast<__int128>(lhs) * static_cast<__int128>(rhs);
 }
 
-inline int128 operator/(int128 lhs, int128 rhs) {
+constexpr int128 operator/(int128 lhs, int128 rhs) {
   return static_cast<__int128>(lhs) / static_cast<__int128>(rhs);
 }
 
-inline int128 operator%(int128 lhs, int128 rhs) {
+constexpr int128 operator%(int128 lhs, int128 rhs) {
   return static_cast<__int128>(lhs) % static_cast<__int128>(rhs);
 }
+#endif // ABSL_HAVE_INTRINSIC_INT128
 
 inline int128 int128::operator++(int) {
   int128 tmp(*this);
diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc
index 13a0e7f..1712af8 100644
--- a/absl/numeric/int128_test.cc
+++ b/absl/numeric/int128_test.cc
@@ -350,7 +350,7 @@
   c = a * b;
   EXPECT_EQ(absl::MakeUint128(0x530EDA741C71D4C3, 0xBF25975319080000), c);
   EXPECT_EQ(0, c - b * a);
-  EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
+  EXPECT_EQ(a * a - b * b, (a + b) * (a - b));
 
   // Verified with dc.
   a = absl::MakeUint128(0x0123456789abcdef, 0xfedcba9876543210);
@@ -358,7 +358,7 @@
   c = a * b;
   EXPECT_EQ(absl::MakeUint128(0x97a87f4f261ba3f2, 0x342d0bbf48948200), c);
   EXPECT_EQ(0, c - b * a);
-  EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
+  EXPECT_EQ(a * a - b * b, (a + b) * (a - b));
 }
 
 TEST(Uint128, AliasTests) {
@@ -462,6 +462,17 @@
   EXPECT_EQ(zero, absl::uint128(0));
   EXPECT_EQ(one, absl::uint128(1));
   EXPECT_EQ(minus_two, absl::MakeUint128(-1, -2));
+
+#ifdef ABSL_HAVE_INTRINSIC_INT128
+  constexpr absl::uint128 division = absl::uint128(10) / absl::uint128(2);
+  EXPECT_EQ(division, absl::uint128(5));
+
+  constexpr absl::uint128 modulus = absl::int128(10) % absl::int128(3);
+  EXPECT_EQ(modulus, absl::uint128(1));
+
+  constexpr absl::uint128 multiplication = absl::uint128(10) * absl::uint128(3);
+  EXPECT_EQ(multiplication, absl::uint128(30));
+#endif  // ABSL_HAVE_INTRINSIC_INT128
 }
 
 TEST(Uint128, NumericLimitsTest) {
@@ -522,7 +533,6 @@
   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(values));
 }
 
-
 TEST(Int128Uint128, ConversionTest) {
   absl::int128 nonnegative_signed_values[] = {
       0,
@@ -540,8 +550,7 @@
   }
 
   absl::int128 negative_values[] = {
-      -1, -0x1234567890abcdef,
-      absl::MakeInt128(-0x5544332211ffeedd, 0),
+      -1, -0x1234567890abcdef, absl::MakeInt128(-0x5544332211ffeedd, 0),
       -absl::MakeInt128(0x76543210fedcba98, 0xabcdef0123456789)};
   for (absl::int128 value : negative_values) {
     EXPECT_EQ(absl::uint128(-value), -absl::uint128(value));
@@ -769,6 +778,17 @@
   EXPECT_EQ(minus_two, absl::MakeInt128(-1, -2));
   EXPECT_GT(max, one);
   EXPECT_LT(min, minus_two);
+
+#ifdef ABSL_HAVE_INTRINSIC_INT128
+  constexpr absl::int128 division = absl::int128(10) / absl::int128(2);
+  EXPECT_EQ(division, absl::int128(5));
+
+  constexpr absl::int128 modulus = absl::int128(10) % absl::int128(3);
+  EXPECT_EQ(modulus, absl::int128(1));
+
+  constexpr absl::int128 multiplication = absl::int128(10) * absl::int128(3);
+  EXPECT_EQ(multiplication, absl::int128(30));
+#endif  // ABSL_HAVE_INTRINSIC_INT128
 }
 
 TEST(Int128, ComparisonTest) {
diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc
index b083975..c17c472 100644
--- a/absl/strings/str_split_test.cc
+++ b/absl/strings/str_split_test.cc
@@ -216,7 +216,7 @@
     std::multimap<std::string, std::string> m =
         absl::StrSplit("a,1,b,2,a,3", ',');
     EXPECT_EQ(3, m.size());
-    auto it = m.find("a");
+    auto it = m.lower_bound("a");
     EXPECT_EQ("1", it->second);
     ++it;
     EXPECT_EQ("3", it->second);
diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h
index 1dc04c5..aaaf60b 100644
--- a/absl/strings/string_view.h
+++ b/absl/strings/string_view.h
@@ -34,7 +34,9 @@
 #include <iosfwd>
 #include <iterator>
 #include <limits>
+#include <memory>
 #include <string>
+#include <type_traits>
 
 #include "absl/base/attributes.h"
 #include "absl/base/nullability.h"
@@ -208,6 +210,16 @@
     ABSL_ASSERT(data != nullptr || len == 0);
   }
 
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+  template <std::contiguous_iterator It, std::sized_sentinel_for<It> End>
+    requires(std::is_same_v<std::iter_value_t<It>, value_type> &&
+             !std::is_convertible_v<End, size_type>)
+  constexpr string_view(It begin, End end)
+      : ptr_(std::to_address(begin)), length_(end - begin) {
+    ABSL_HARDENING_ASSERT(end >= begin);
+  }
+#endif  // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+
   constexpr string_view(const string_view&) noexcept = default;
   string_view& operator=(const string_view&) noexcept = default;
 
diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc
index adf4d1b..c5d15c7 100644
--- a/absl/strings/string_view_test.cc
+++ b/absl/strings/string_view_test.cc
@@ -16,6 +16,7 @@
 
 #include <stdlib.h>
 
+#include <array>
 #include <cstddef>
 #include <cstdlib>
 #include <cstring>
@@ -131,6 +132,23 @@
     EXPECT_EQ(8u, s31.length());
   }
 
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+  {
+    // Iterator constructor
+    std::string str = "hello";
+    absl::string_view s1(str.begin(), str.end());
+    EXPECT_EQ(s1, "hello");
+
+    std::array<char, 3> arr = { '1', '2', '3' };
+    absl::string_view s2(arr.begin(), arr.end());
+    EXPECT_EQ(s2, "123");
+
+    const char carr[] = "carr";
+    absl::string_view s3(carr, carr + strlen(carr));
+    EXPECT_EQ(s3, "carr");
+  }
+#endif  // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+
   {
     using mstring =
         std::basic_string<char, std::char_traits<char>, Mallocator<char>>;
@@ -1154,6 +1172,18 @@
 
   constexpr size_t sp_npos = sp.npos;
   EXPECT_EQ(sp_npos, static_cast<size_t>(-1));
+
+#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
+  {
+    static constexpr std::array<char, 3> arr = { '1', '2', '3' };
+    constexpr absl::string_view s2(arr.begin(), arr.end());
+    EXPECT_EQ(s2, "123");
+
+    static constexpr char carr[] = "carr";
+    constexpr absl::string_view s3(carr, carr + 4);
+    EXPECT_EQ(s3, "carr");
+  }
+#endif  // ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
 }
 
 constexpr char ConstexprMethodsHelper() {