[libc-commits] [libc] [libc][stdlib] Add Block class (PR #94407)

via libc-commits libc-commits at lists.llvm.org
Wed Jun 5 14:23:35 PDT 2024


================
@@ -0,0 +1,473 @@
+//===-- Implementation header for a block of memory -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_BLOCK_H
+#define LLVM_LIBC_SRC_STDLIB_BLOCK_H
+
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/cstddef.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/CPP/new.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/CPP/type_traits.h"
+
+#include <stdint.h>
+
+namespace LIBC_NAMESPACE {
+
+namespace internal {
+// Types of corrupted blocks, and functions to crash with an error message
+// corresponding to each type.
+enum BlockStatus {
+  kValid,
+  kMisaligned,
+  kPrevMismatched,
+  kNextMismatched,
+};
+} // namespace internal
+
+/// Returns the value rounded down to the nearest multiple of alignment.
+constexpr size_t AlignDown(size_t value, size_t alignment) {
+  __builtin_mul_overflow(value / alignment, alignment, &value);
----------------
PiJoules wrote:

So that particular clang snippet is checking that the operands fit into 32 bits. If it does, then use the equivalent 32-bit operations, otherwise default to the 64-bit ones. Clang does this to avoid slow divs on x86 which I suppose are slower vs 32-bit diffs enough to warrent a branch. This looks to only be enabled at O3 and O2 but Oz will produce the smaller snippet.

The check for bypassing the slow division is at https://github.com/llvm/llvm-project/blob/f8afa763c6194f5bf485480e1fb94b953942f876/llvm/lib/CodeGen/CodeGenPrepare.cpp#L603 and the logic for doing the replacement with branches is https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Utils/BypassSlowDivision.cpp#L448 and for x86 specifically, we satisfy the checking condition here
```
  // Bypass expensive divides and use cheaper ones.
  if (TM.getOptLevel() >= CodeGenOptLevel::Default) {
    if (Subtarget.hasSlowDivide32())
      addBypassSlowDiv(32, 8);
    if (Subtarget.hasSlowDivide64() && Subtarget.is64Bit())
      addBypassSlowDiv(64, 32);
  }
```

So it looks like this is WAI for x86-64 at -O3.

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


More information about the libc-commits mailing list