Roll abseil_revision f3489c9ca6..3204cc0625

Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/f3489c9ca6..3204cc0625
Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/f3489c9ca6..3204cc0625

No .def changes

Bug: None
Change-Id: I666ba059222363b4e911099b56006d0b5930de8c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3560462
Reviewed-by: Mirko Bonadei <mbonadei@chromium.org>
Commit-Queue: Danil Chapovalov <danilchap@chromium.org>
Cr-Commit-Position: refs/heads/main@{#987079}
NOKEYCHECK=True
GitOrigin-RevId: a19b527d9946b12775d0e9765ade706b8c390543
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index 0becc7a..518c469 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -78,7 +78,6 @@
   "container/internal/hashtablez_sampler.cc"
   "container/internal/hashtablez_sampler.h"
   "container/internal/hashtablez_sampler_force_weak_definition.cc"
-  "container/internal/have_sse.h"
   "container/internal/inlined_vector.h"
   "container/internal/layout.h"
   "container/internal/node_slot_policy.h"
@@ -456,7 +455,6 @@
   "hashtablez_sampler"
   "hashtable_debug"
   "hashtable_debug_hooks"
-  "have_sse"
   "node_slot_policy"
   "raw_hash_map"
   "container_common"
diff --git a/README.chromium b/README.chromium
index 4a64d5b..9723fe1 100644
--- a/README.chromium
+++ b/README.chromium
@@ -4,7 +4,7 @@
 License: Apache 2.0
 License File: LICENSE
 Version: 0
-Revision: f3489c9ca64e0fad2a263e8560ee96718ac8b21b
+Revision: 3204cc0625230e9876f0310a6dea0014210ab325
 Security Critical: yes
 
 Description:
diff --git a/WORKSPACE b/WORKSPACE
index 8120cd1..1a1753a 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -35,6 +35,13 @@
     urls = ["https://github.com/google/benchmark/archive/0baacde3618ca617da95375e0af13ce1baadea47.zip"],
 )
 
+# Bazel Skylib.
+http_archive(
+    name = "bazel_skylib",
+    urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz"],
+    sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728",
+)
+
 # Bazel platform rules.
 http_archive(
     name = "platforms",
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index d799b7f..7cccbbb 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -13,6 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
 package(default_visibility = ["//visibility:public"])
 
 licenses(["notice"])
@@ -64,7 +66,15 @@
 )
 
 config_setting(
-    name = "wasm",
+    name = "cpu_wasm",
+    values = {
+        "cpu": "wasm",
+    },
+    visibility = [":__subpackages__"],
+)
+
+config_setting(
+    name = "cpu_wasm32",
     values = {
         "cpu": "wasm32",
     },
@@ -72,6 +82,33 @@
 )
 
 config_setting(
+    name = "platforms_wasm32",
+    constraint_values = [
+        "@platforms//cpu:wasm32",
+    ],
+    visibility = [":__subpackages__"],
+)
+
+config_setting(
+    name = "platforms_wasm64",
+    constraint_values = [
+        "@platforms//cpu:wasm64",
+    ],
+    visibility = [":__subpackages__"],
+)
+
+selects.config_setting_group(
+    name = "wasm",
+    match_any = [
+        ":cpu_wasm",
+        ":cpu_wasm32",
+        ":platforms_wasm32",
+        ":platforms_wasm64",
+    ],
+    visibility = [":__subpackages__"],
+)
+
+config_setting(
     name = "fuchsia",
     values = {
         "cpu": "fuchsia",
diff --git a/absl/base/config.h b/absl/base/config.h
index 8c100d8..429dd35 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -269,6 +269,8 @@
 #define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1
 #elif ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0)
 #define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1
+#elif defined(_MSC_VER) && _MSC_VER >= 1926
+#define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1
 #endif
 #endif
 
@@ -414,7 +416,8 @@
     defined(_AIX) || defined(__ros__) || defined(__native_client__) ||    \
     defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__) ||    \
     defined(__sun) || defined(__ASYLO__) || defined(__myriad2__) ||       \
-    defined(__HAIKU__) || defined(__OpenBSD__) || defined(__NetBSD__)
+    defined(__HAIKU__) || defined(__OpenBSD__) || defined(__NetBSD__) ||  \
+    defined(__QNX__)
 #define ABSL_HAVE_MMAP 1
 #endif
 
@@ -817,4 +820,34 @@
 #define ABSL_INTERNAL_HAS_RTTI 1
 #endif  // !defined(__GNUC__) || defined(__GXX_RTTI)
 
+// ABSL_INTERNAL_HAVE_SSE2 is used for compile-time detection of SSE2 support.
+// See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html for an overview of
+// which architectures support the various x86 instruction sets.
+#ifdef ABSL_INTERNAL_HAVE_SSE2
+#error ABSL_INTERNAL_HAVE_SSE2 cannot be directly set
+#elif defined(__SSE2__)
+#define ABSL_INTERNAL_HAVE_SSE2 1
+#elif defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
+// MSVC only defines _M_IX86_FP for x86 32-bit code, and _M_IX86_FP >= 2
+// indicates that at least SSE2 was targeted with the /arch:SSE2 option.
+// All x86-64 processors support SSE2, so support can be assumed.
+// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
+#define ABSL_INTERNAL_HAVE_SSE2 1
+#endif
+
+// ABSL_INTERNAL_HAVE_SSSE3 is used for compile-time detection of SSSE3 support.
+// See https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html for an overview of
+// which architectures support the various x86 instruction sets.
+//
+// MSVC does not have a mode that targets SSSE3 at compile-time. To use SSSE3
+// with MSVC requires either assuming that the code will only every run on CPUs
+// that support SSSE3, otherwise __cpuid() can be used to detect support at
+// runtime and fallback to a non-SSSE3 implementation when SSSE3 is unsupported
+// by the CPU.
+#ifdef ABSL_INTERNAL_HAVE_SSSE3
+#error ABSL_INTERNAL_HAVE_SSSE3 cannot be directly set
+#elif defined(__SSSE3__)
+#define ABSL_INTERNAL_HAVE_SSSE3 1
+#endif
+
 #endif  // ABSL_BASE_CONFIG_H_
diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h
index dad0e9a..50747d7 100644
--- a/absl/base/internal/endian.h
+++ b/absl/base/internal/endian.h
@@ -16,16 +16,9 @@
 #ifndef ABSL_BASE_INTERNAL_ENDIAN_H_
 #define ABSL_BASE_INTERNAL_ENDIAN_H_
 
-// The following guarantees declaration of the byte swap functions
-#ifdef _MSC_VER
-#include <stdlib.h>  // NOLINT(build/include)
-#elif defined(__FreeBSD__)
-#include <sys/endian.h>
-#elif defined(__GLIBC__)
-#include <byteswap.h>  // IWYU pragma: export
-#endif
-
 #include <cstdint>
+#include <cstdlib>
+
 #include "absl/base/casts.h"
 #include "absl/base/config.h"
 #include "absl/base/internal/unaligned_access.h"
@@ -34,47 +27,11 @@
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
-// Use compiler byte-swapping intrinsics if they are available.  32-bit
-// and 64-bit versions are available in Clang and GCC as of GCC 4.3.0.
-// The 16-bit version is available in Clang and GCC only as of GCC 4.8.0.
-// For simplicity, we enable them all only for GCC 4.8.0 or later.
-#if defined(__clang__) || \
-    (defined(__GNUC__) && \
-     ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
 inline uint64_t gbswap_64(uint64_t host_int) {
+#if ABSL_HAVE_BUILTIN(__builtin_bswap64) || defined(__GNUC__)
   return __builtin_bswap64(host_int);
-}
-inline uint32_t gbswap_32(uint32_t host_int) {
-  return __builtin_bswap32(host_int);
-}
-inline uint16_t gbswap_16(uint16_t host_int) {
-  return __builtin_bswap16(host_int);
-}
-
 #elif defined(_MSC_VER)
-inline uint64_t gbswap_64(uint64_t host_int) {
   return _byteswap_uint64(host_int);
-}
-inline uint32_t gbswap_32(uint32_t host_int) {
-  return _byteswap_ulong(host_int);
-}
-inline uint16_t gbswap_16(uint16_t host_int) {
-  return _byteswap_ushort(host_int);
-}
-
-#else
-inline uint64_t gbswap_64(uint64_t host_int) {
-#if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__)
-  // Adapted from /usr/include/byteswap.h.  Not available on Mac.
-  if (__builtin_constant_p(host_int)) {
-    return __bswap_constant_64(host_int);
-  } else {
-    uint64_t result;
-    __asm__("bswap %0" : "=r"(result) : "0"(host_int));
-    return result;
-  }
-#elif defined(__GLIBC__)
-  return bswap_64(host_int);
 #else
   return (((host_int & uint64_t{0xFF}) << 56) |
           ((host_int & uint64_t{0xFF00}) << 40) |
@@ -84,12 +41,14 @@
           ((host_int & uint64_t{0xFF0000000000}) >> 24) |
           ((host_int & uint64_t{0xFF000000000000}) >> 40) |
           ((host_int & uint64_t{0xFF00000000000000}) >> 56));
-#endif  // bswap_64
+#endif
 }
 
 inline uint32_t gbswap_32(uint32_t host_int) {
-#if defined(__GLIBC__)
-  return bswap_32(host_int);
+#if ABSL_HAVE_BUILTIN(__builtin_bswap32) || defined(__GNUC__)
+  return __builtin_bswap32(host_int);
+#elif defined(_MSC_VER)
+  return _byteswap_ulong(host_int);
 #else
   return (((host_int & uint32_t{0xFF}) << 24) |
           ((host_int & uint32_t{0xFF00}) << 8) |
@@ -99,33 +58,29 @@
 }
 
 inline uint16_t gbswap_16(uint16_t host_int) {
-#if defined(__GLIBC__)
-  return bswap_16(host_int);
+#if ABSL_HAVE_BUILTIN(__builtin_bswap16) || defined(__GNUC__)
+  return __builtin_bswap16(host_int);
+#elif defined(_MSC_VER)
+  return _byteswap_ushort(host_int);
 #else
   return (((host_int & uint16_t{0xFF}) << 8) |
           ((host_int & uint16_t{0xFF00}) >> 8));
 #endif
 }
 
-#endif  // intrinsics available
-
 #ifdef ABSL_IS_LITTLE_ENDIAN
 
-// Definitions for ntohl etc. that don't require us to include
-// netinet/in.h. We wrap gbswap_32 and gbswap_16 in functions rather
-// than just #defining them because in debug mode, gcc doesn't
-// correctly handle the (rather involved) definitions of bswap_32.
-// gcc guarantees that inline functions are as fast as macros, so
-// this isn't a performance hit.
+// Portable definitions for htonl (host-to-network) and friends on little-endian
+// architectures.
 inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); }
 inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); }
 inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); }
 
 #elif defined ABSL_IS_BIG_ENDIAN
 
-// These definitions are simpler on big-endian machines
-// These are functions instead of macros to avoid self-assignment warnings
-// on calls such as "i = ghtnol(i);".  This also provides type checking.
+// Portable definitions for htonl (host-to-network) etc on big-endian
+// architectures. These definitions are simpler since the host byte order is the
+// same as network byte order.
 inline uint16_t ghtons(uint16_t x) { return x; }
 inline uint32_t ghtonl(uint32_t x) { return x; }
 inline uint64_t ghtonll(uint64_t x) { return x; }
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index bc25bac..2095e57 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -509,8 +509,8 @@
     copts = ABSL_DEFAULT_COPTS,
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
-        ":have_sse",
         "//absl/base",
+        "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/debugging:stacktrace",
         "//absl/memory",
@@ -527,7 +527,7 @@
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         ":hashtablez_sampler",
-        ":have_sse",
+        "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/profiling:sample_recorder",
         "//absl/synchronization",
@@ -570,14 +570,6 @@
 )
 
 cc_library(
-    name = "have_sse",
-    hdrs = ["internal/have_sse.h"],
-    copts = ABSL_DEFAULT_COPTS,
-    linkopts = ABSL_DEFAULT_LINKOPTS,
-    visibility = ["//visibility:private"],
-)
-
-cc_library(
     name = "common",
     hdrs = ["internal/common.h"],
     copts = ABSL_DEFAULT_COPTS,
@@ -601,7 +593,6 @@
         ":hash_policy_traits",
         ":hashtable_debug_hooks",
         ":hashtablez_sampler",
-        ":have_sse",
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:endian",
diff --git a/absl/container/BUILD.gn b/absl/container/BUILD.gn
index a90e7b7..b4167aa 100644
--- a/absl/container/BUILD.gn
+++ b/absl/container/BUILD.gn
@@ -172,8 +172,8 @@
     "internal/hashtablez_sampler_force_weak_definition.cc",
   ]
   deps = [
-    ":have_sse",
     "//third_party/abseil-cpp/absl/base",
+    "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/debugging:stacktrace",
     "//third_party/abseil-cpp/absl/memory",
@@ -209,11 +209,6 @@
   ]
 }
 
-absl_source_set("have_sse") {
-  public = [ "internal/have_sse.h" ]
-  visibility = [ ":*" ]
-}
-
 absl_source_set("common") {
   public = [ "internal/common.h" ]
   deps = [
@@ -232,7 +227,6 @@
     ":hash_policy_traits",
     ":hashtable_debug_hooks",
     ":hashtablez_sampler",
-    ":have_sse",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/base:endian",
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index 648a3db..7176907 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -550,8 +550,8 @@
     ${ABSL_DEFAULT_COPTS}
   DEPS
     absl::base
+    absl::config
     absl::exponential_biased
-    absl::have_sse
     absl::sample_recorder
     absl::synchronization
 )
@@ -564,8 +564,8 @@
   COPTS
     ${ABSL_TEST_COPTS}
   DEPS
+    absl::config
     absl::hashtablez_sampler
-    absl::have_sse
     GTest::gmock_main
 )
 
@@ -594,15 +594,6 @@
 
 absl_cc_library(
   NAME
-    have_sse
-  HDRS
-    "internal/have_sse.h"
-  COPTS
-    ${ABSL_DEFAULT_COPTS}
-)
-
-absl_cc_library(
-  NAME
     node_slot_policy
   HDRS
     "internal/node_slot_policy.h"
@@ -670,7 +661,6 @@
     absl::endian
     absl::hash_policy_traits
     absl::hashtable_debug_hooks
-    absl::have_sse
     absl::memory
     absl::meta
     absl::optional
diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc
index 322e054..c6036d5 100644
--- a/absl/container/internal/hashtablez_sampler.cc
+++ b/absl/container/internal/hashtablez_sampler.cc
@@ -21,7 +21,7 @@
 #include <limits>
 
 #include "absl/base/attributes.h"
-#include "absl/container/internal/have_sse.h"
+#include "absl/base/config.h"
 #include "absl/debugging/stacktrace.h"
 #include "absl/memory/memory.h"
 #include "absl/profiling/internal/exponential_biased.h"
@@ -160,7 +160,7 @@
   // SwissTables probe in groups of 16, so scale this to count items probes and
   // not offset from desired.
   size_t probe_length = distance_from_desired;
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
+#ifdef ABSL_INTERNAL_HAVE_SSE2
   probe_length /= 16;
 #else
   probe_length /= 8;
diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h
index e7c204e..d4016d8 100644
--- a/absl/container/internal/hashtablez_sampler.h
+++ b/absl/container/internal/hashtablez_sampler.h
@@ -44,9 +44,9 @@
 #include <memory>
 #include <vector>
 
+#include "absl/base/config.h"
 #include "absl/base/internal/per_thread_tls.h"
 #include "absl/base/optimization.h"
-#include "absl/container/internal/have_sse.h"
 #include "absl/profiling/internal/sample_recorder.h"
 #include "absl/synchronization/mutex.h"
 #include "absl/utility/utility.h"
@@ -96,7 +96,7 @@
 };
 
 inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) {
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
+#ifdef ABSL_INTERNAL_HAVE_SSE2
   total_probe_length /= 16;
 #else
   total_probe_length /= 8;
diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc
index 77cdf2f..665d518 100644
--- a/absl/container/internal/hashtablez_sampler_test.cc
+++ b/absl/container/internal/hashtablez_sampler_test.cc
@@ -21,7 +21,7 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "absl/base/attributes.h"
-#include "absl/container/internal/have_sse.h"
+#include "absl/base/config.h"
 #include "absl/profiling/internal/sample_recorder.h"
 #include "absl/synchronization/blocking_counter.h"
 #include "absl/synchronization/internal/thread_pool.h"
@@ -30,7 +30,7 @@
 #include "absl/time/clock.h"
 #include "absl/time/time.h"
 
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
+#ifdef ABSL_INTERNAL_HAVE_SSE2
 constexpr int kProbeLength = 16;
 #else
 constexpr int kProbeLength = 8;
diff --git a/absl/container/internal/have_sse.h b/absl/container/internal/have_sse.h
deleted file mode 100644
index e75e1a1..0000000
--- a/absl/container/internal/have_sse.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// Shared config probing for SSE instructions used in Swiss tables.
-#ifndef ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_
-#define ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_
-
-#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
-#if defined(__SSE2__) ||  \
-    (defined(_MSC_VER) && \
-     (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2)))
-#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 1
-#else
-#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 0
-#endif
-#endif
-
-#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
-#ifdef __SSSE3__
-#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 1
-#else
-#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 0
-#endif
-#endif
-
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 && \
-    !ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
-#error "Bad configuration!"
-#endif
-
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
-#include <emmintrin.h>
-#endif
-
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
-#include <tmmintrin.h>
-#endif
-
-#endif  // ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index d24bbe8..046a693 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -88,7 +88,7 @@
 // +---------------+---------------+---------------+
 //
 // Each control byte is either a special value for empty slots, deleted slots
-// (sometimes called *tombstones*), and a speical end-of-table marker used by
+// (sometimes called *tombstones*), and a special end-of-table marker used by
 // iterators, or, if occupied, seven bits (H2) from the hash of the value in the
 // corresponding slot.
 //
@@ -130,7 +130,7 @@
 //  7 | 0.191 | 15 | 0.879
 //
 // The rule of thumb breaks down at around `n = 12`, but such groups would only
-// occur for tables close to their load factor. This is far better than an
+// occur for tables close to their max load factor. This is far better than an
 // ordinary open-addressing table, which needs to perform an == at every step of
 // the probe sequence. These probabilities don't tell the full story (for
 // example, because elements are inserted into a group from the front, and
@@ -155,7 +155,7 @@
 // this point, we may `unchecked_insert` the value `x`.
 //
 // Below, `unchecked_insert` is partly implemented by `prepare_insert`, which
-// presents a viable, intialized slot pointee to the caller.
+// presents a viable, initialized slot pointee to the caller.
 //
 // `erase` is implemented in terms of `erase_at`, which takes an index to a
 // slot. Given an offset, we simply create a tombstone and destroy its contents.
@@ -176,6 +176,18 @@
 #ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
 #define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
 
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+#ifdef __SSSE3__
+#include <tmmintrin.h>
+#endif
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
 #include <algorithm>
 #include <cmath>
 #include <cstdint>
@@ -187,6 +199,7 @@
 #include <type_traits>
 #include <utility>
 
+#include "absl/base/config.h"
 #include "absl/base/internal/endian.h"
 #include "absl/base/optimization.h"
 #include "absl/base/port.h"
@@ -196,7 +209,6 @@
 #include "absl/container/internal/hash_policy_traits.h"
 #include "absl/container/internal/hashtable_debug_hooks.h"
 #include "absl/container/internal/hashtablez_sampler.h"
-#include "absl/container/internal/have_sse.h"
 #include "absl/memory/memory.h"
 #include "absl/meta/type_traits.h"
 #include "absl/numeric/bits.h"
@@ -229,7 +241,7 @@
 //
 // Wrapping around at `mask + 1` is important, but not for the obvious reason.
 // As described above, the first few entries of the control byte array
-// is mirrored at the end of the array, which `Group` will find and use
+// are mirrored at the end of the array, which `Group` will find and use
 // for selecting candidates. However, when those candidates' slots are
 // actually inspected, there are no corresponding slots for the cloned bytes,
 // so we need to make sure we've treated those offsets as "wrapping around".
@@ -300,7 +312,7 @@
   return static_cast<uint32_t>(countr_zero(x));
 }
 
-// A abstract bitmask, such as that emitted by a SIMD instruction.
+// An abstract bitmask, such as that emitted by a SIMD instruction.
 //
 // Specifically, this type implements a simple bitset whose representation is
 // controlled by `SignificantBits` and `Shift`. `SignificantBits` is the number
@@ -452,7 +464,7 @@
 
 // Extracts the H2 portion of a hash: the 7 bits not used for H1.
 //
-// Thse are used used as an occupied control byte.
+// These are used as an occupied control byte.
 inline h2_t H2(size_t hash) { return hash & 0x7F; }
 
 // Helpers for checking the state of a control byte.
@@ -461,8 +473,8 @@
 inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; }
 inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; }
 
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
-// Quick eference guide for intrinsics used below:
+#ifdef ABSL_INTERNAL_HAVE_SSE2
+// Quick reference guide for intrinsics used below:
 //
 // * __m128i: An XMM (128-bit) word.
 //
@@ -479,7 +491,7 @@
 // * _mm_cmpgt_epi8: Same as above, but using > rather than ==.
 //
 // * _mm_loadu_si128:  Performs an unaligned load of an i128.
-// * _mm_storeu_si128: Performs an unaligned store of a i128.
+// * _mm_storeu_si128: Performs an unaligned store of an i128.
 //
 // * _mm_sign_epi8:     Retains, negates, or zeroes each i8 lane of the first
 //                      argument if the corresponding lane of the second
@@ -522,7 +534,7 @@
 
   // Returns a bitmask representing the positions of empty slots.
   BitMask<uint32_t, kWidth> MatchEmpty() const {
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
+#ifdef ABSL_INTERNAL_HAVE_SSSE3
     // This only works because ctrl_t::kEmpty is -128.
     return BitMask<uint32_t, kWidth>(
         static_cast<uint32_t>(_mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))));
@@ -548,7 +560,7 @@
   void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
     auto msbs = _mm_set1_epi8(static_cast<char>(-128));
     auto x126 = _mm_set1_epi8(126);
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3
+#ifdef ABSL_INTERNAL_HAVE_SSSE3
     auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs);
 #else
     auto zero = _mm_setzero_si128();
@@ -614,7 +626,7 @@
   uint64_t ctrl;
 };
 
-#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2
+#ifdef ABSL_INTERNAL_HAVE_SSE2
 using Group = GroupSse2Impl;
 #else
 using Group = GroupPortableImpl;
@@ -700,13 +712,8 @@
   return 0;
 }
 
-inline void AssertIsFull(ctrl_t* ctrl) {
-  ABSL_HARDENING_ASSERT(
-      (ctrl != nullptr && IsFull(*ctrl)) &&
-      "Invalid operation on iterator. The element might have "
-      "been erased, the table might have rehashed, or this may "
-      "be an end() iterator.");
-}
+#define ABSL_INTERNAL_ASSERT_IS_FULL(ctrl, msg) \
+  ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && msg)
 
 inline void AssertIsValid(ctrl_t* ctrl) {
   ABSL_HARDENING_ASSERT(
@@ -731,7 +738,7 @@
 // In small mode only the first `capacity` control bytes after the sentinel
 // are valid. The rest contain dummy ctrl_t::kEmpty values that do not
 // represent a real slot. This is important to take into account on
-// `find_first_or_null()`, where we never try
+// `find_first_non_full()`, where we never try
 // `ShouldInsertBackwards()` for small tables.
 inline bool is_small(size_t capacity) { return capacity < Group::kWidth - 1; }
 
@@ -778,7 +785,7 @@
 extern template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t);
 
 // Sets `ctrl` to `{kEmpty, kSentinel, ..., kEmpty}`, marking the entire
-// array as deleted.
+// array as marked as empty.
 inline void ResetCtrl(size_t capacity, ctrl_t* ctrl, const void* slot,
                       size_t slot_size) {
   std::memset(ctrl, static_cast<int8_t>(ctrl_t::kEmpty),
@@ -942,16 +949,22 @@
 
     // PRECONDITION: not an end() iterator.
     reference operator*() const {
-      AssertIsFull(ctrl_);
+      ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
+                                   "operator*() called on invalid iterator.");
       return PolicyTraits::element(slot_);
     }
 
     // PRECONDITION: not an end() iterator.
-    pointer operator->() const { return &operator*(); }
+    pointer operator->() const {
+      ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
+                                   "operator-> called on invalid iterator.");
+      return &operator*();
+    }
 
     // PRECONDITION: not an end() iterator.
     iterator& operator++() {
-      AssertIsFull(ctrl_);
+      ABSL_INTERNAL_ASSERT_IS_FULL(ctrl_,
+                                   "operator++ called on invalid iterator.");
       ++ctrl_;
       ++slot_;
       skip_empty_or_deleted();
@@ -1500,7 +1513,8 @@
   // This overload is necessary because otherwise erase<K>(const K&) would be
   // a better match if non-const iterator is passed as an argument.
   void erase(iterator it) {
-    AssertIsFull(it.ctrl_);
+    ABSL_INTERNAL_ASSERT_IS_FULL(it.ctrl_,
+                                 "erase() called on invalid iterator.");
     PolicyTraits::destroy(&alloc_ref(), it.slot_);
     erase_meta_only(it);
   }
@@ -1534,7 +1548,8 @@
   }
 
   node_type extract(const_iterator position) {
-    AssertIsFull(position.inner_.ctrl_);
+    ABSL_INTERNAL_ASSERT_IS_FULL(position.inner_.ctrl_,
+                                 "extract() called on invalid iterator.");
     auto node =
         CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_);
     erase_meta_only(position);
@@ -2263,4 +2278,6 @@
 ABSL_NAMESPACE_END
 }  // namespace absl
 
+#undef ABSL_INTERNAL_ASSERT_IS_FULL
+
 #endif  // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index e7732f6..9cd88a2 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -2030,7 +2030,7 @@
 
   IntTable t;
   // Extra simple "regexp" as regexp support is highly varied across platforms.
-  constexpr char kDeathMsg[] = "Invalid operation on iterator";
+  constexpr char kDeathMsg[] = "erase.. called on invalid iterator";
   EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg);
 }
 
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc
index 689e597..3fe8827 100644
--- a/absl/debugging/failure_signal_handler.cc
+++ b/absl/debugging/failure_signal_handler.cc
@@ -52,7 +52,7 @@
 #define ABSL_HAVE_SIGACTION
 // Apple WatchOS and TVOS don't allow sigaltstack
 #if !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \
-    !(defined(TARGET_OS_TV) && TARGET_OS_TV)
+    !(defined(TARGET_OS_TV) && TARGET_OS_TV) && !defined(__QNX__)
 #define ABSL_HAVE_SIGALTSTACK
 #endif
 #endif
diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h
index be20256..e4bbf2d 100644
--- a/absl/debugging/internal/elf_mem_image.h
+++ b/absl/debugging/internal/elf_mem_image.h
@@ -31,7 +31,7 @@
 #error ABSL_HAVE_ELF_MEM_IMAGE cannot be directly set
 #endif
 
-#if defined(__ELF__) && !defined(__OpenBSD__) && \
+#if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) &&  \
     !defined(__native_client__) && !defined(__asmjs__) && !defined(__wasm__)
 #define ABSL_HAVE_ELF_MEM_IMAGE 1
 #endif
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index f810333..45dfdd4 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -1090,15 +1090,10 @@
   }
 
   ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t Mix(uint64_t state, uint64_t v) {
-#if defined(__aarch64__)
-    // On AArch64, calculating a 128-bit product is inefficient, because it
-    // requires a sequence of two instructions to calculate the upper and lower
-    // halves of the result.
-    using MultType = uint64_t;
-#else
+    // Though the 128-bit product on AArch64 needs two instructions, it is
+    // still a good balance between speed and hash quality.
     using MultType =
         absl::conditional_t<sizeof(size_t) == 4, uint64_t, uint128>;
-#endif
     // We do the addition in 64-bit space to make sure the 128-bit
     // multiplication is fast. If we were to do it as MultType the compiler has
     // to assume that the high word is non-zero and needs to perform 2
diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h
index 3ed2466..86c84ed 100644
--- a/absl/strings/numbers.h
+++ b/absl/strings/numbers.h
@@ -23,8 +23,12 @@
 #ifndef ABSL_STRINGS_NUMBERS_H_
 #define ABSL_STRINGS_NUMBERS_H_
 
-#ifdef __SSE4_2__
-#include <x86intrin.h>
+#ifdef __SSSE3__
+#include <tmmintrin.h>
+#endif
+
+#ifdef _MSC_VER
+#include <intrin.h>
 #endif
 
 #include <cstddef>
@@ -36,14 +40,7 @@
 #include <type_traits>
 
 #include "absl/base/config.h"
-#ifdef __SSE4_2__
-// TODO(jorg): Remove this when we figure out the right way
-// to swap bytes on SSE 4.2 that works with the compilers
-// we claim to support.  Also, add tests for the compiler
-// that doesn't support the Intel _bswap64 intrinsic but
-// does support all the SSE 4.2 intrinsics
 #include "absl/base/internal/endian.h"
-#endif
 #include "absl/base/macros.h"
 #include "absl/base/port.h"
 #include "absl/numeric/bits.h"
@@ -246,7 +243,7 @@
 // Returns the number of non-pad digits of the output (it can never be zero
 // since 0 has one digit).
 inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
-#ifdef __SSE4_2__
+#ifdef ABSL_INTERNAL_HAVE_SSSE3
   uint64_t be = absl::big_endian::FromHost64(val);
   const auto kNibbleMask = _mm_set1_epi8(0xf);
   const auto kHexDigits = _mm_setr_epi8('0', '1', '2', '3', '4', '5', '6', '7',