Disable mask-based implementation when SVE CLZ is present, since that allows vectorizing the scalar implementation.

PiperOrigin-RevId: 588950163
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index 2fd3142..7789f92 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -685,11 +685,13 @@
   return sum;
 }
 
-// GCC does not recognize the vectorization opportunity
-// and other platforms are untested, in those cases using the optimized
-// varint size routine for each element is faster.
-// Hence we enable it only for clang
-#if (defined(__SSE__) || defined(__aarch64__)) && defined(__clang__)
+// On machines without a vector count-leading-zeros instruction such as SVE CLZ
+// on arm or VPLZCNT on x86, SSE or AVX2 instructions can allow vectorization of
+// the size calculation loop. GCC does not detect this autovectorization
+// opportunity, so only enable for clang.
+// When last tested, AVX512-vectorized lzcnt was slower than the SSE/AVX2
+// implementation, so __AVX512CD__ is not checked.
+#if defined(__SSE__) && defined(__clang__)
 size_t WireFormatLite::Int32Size(const RepeatedField<int32_t>& value) {
   return VarintSize<false, true>(value.data(), value.size());
 }
@@ -707,7 +709,7 @@
   return VarintSize<false, true>(value.data(), value.size());
 }
 
-#else  // !((defined(__SSE__) || defined(__aarch64__) && defined(__clang__))
+#else  // !(defined(__SSE__) && defined(__clang__))
 
 size_t WireFormatLite::Int32Size(const RepeatedField<int32_t>& value) {
   size_t out = 0;