Improve the way we mask the bits for `_internal_metadata_`.

For the arena, no need to mask anything.
For the container, we use arithmetic instead of masks. The arithmetic is smaller and can be merged with another operation.

PiperOrigin-RevId: 847830188
diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h
index 6425863..df190d3 100644
--- a/src/google/protobuf/metadata_lite.h
+++ b/src/google/protobuf/metadata_lite.h
@@ -11,6 +11,7 @@
 #include <string>
 
 #include "absl/base/optimization.h"
+#include "absl/log/absl_check.h"
 #include "google/protobuf/arena.h"
 #include "google/protobuf/port.h"
 
@@ -145,7 +146,19 @@
 
   template <typename U>
   U* PtrValue() const {
-    return reinterpret_cast<U*>(ptr_ & kPtrValueMask);
+    if constexpr (std::is_same_v<U, Arena>) {
+      // No mask to remove.
+      ABSL_DCHECK_EQ(ptr_ & kPtrTagMask, 0);
+      return reinterpret_cast<U*>(ptr_);
+    } else {
+      static_assert(kPtrTagMask == 1);
+      ABSL_DCHECK_EQ(ptr_ & kPtrTagMask, kPtrTagMask);
+      // We can remove the mask via -1, which is smaller asm and can be merged
+      // with other arithmetic operations.
+      // Eg PtrValue<Container>()->unknown_fields can merge the offset into the
+      // mask removal.
+      return reinterpret_cast<U*>(ptr_ - kPtrTagMask);
+    }
   }
 
   // If ptr_'s tag is kTagContainer, it points to an instance of this struct.