[llvm] Clean up / speed up ULEB128 decoding (PR #73585)

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 28 08:45:28 PST 2023


================
@@ -125,29 +125,30 @@ inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
 }
 
 /// Utility function to decode a ULEB128 value.
+///
+/// If \p error is non-null, it will point to a static error message,
+/// if an error occured. It will not be modified on success.
 inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr,
                               const uint8_t *end = nullptr,
                               const char **error = nullptr) {
   const uint8_t *orig_p = p;
   uint64_t Value = 0;
   unsigned Shift = 0;
-  if (error)
-    *error = nullptr;
   do {
-    if (p == end) {
+    if (LLVM_UNLIKELY(p == end)) {
       if (error)
         *error = "malformed uleb128, extends past end";
-      if (n)
-        *n = (unsigned)(p - orig_p);
-      return 0;
+      Value = 0;
+      break;
     }
     uint64_t Slice = *p & 0x7f;
-    if ((Shift >= 64 && Slice != 0) || Slice << Shift >> Shift != Slice) {
+    if (LLVM_UNLIKELY(Shift >= 63) &&
+        ((Shift == 63 && ((Slice << Shift) >> Shift) != Slice) ||
----------------
adrian-prantl wrote:

I only added this for better readability. At first glance `x << Shift >> Shift ` looks like a noop otherwise.

https://github.com/llvm/llvm-project/pull/73585


More information about the llvm-commits mailing list