[libc] [llvm] [libc] Add fixed point support to printf (PR #82707)

Michael Jones via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 26 14:37:26 PST 2024


================
@@ -0,0 +1,144 @@
+//===-- printf_fixed_conv_fuzz.cpp ----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc printf %f/e/g/a implementations.
+///
+//===----------------------------------------------------------------------===//
+#include "src/stdio/snprintf.h"
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/fixed_point/fx_rep.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "utils/MPFRWrapper/mpfr_inc.h"
+
+constexpr int MAX_SIZE = 10000;
+
+inline bool simple_streq(char *first, char *second, int length) {
+  for (int i = 0; i < length; ++i) {
+    if (first[i] != second[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+enum class TestResult {
+  Success,
+  BufferSizeFailed,
+  LengthsDiffer,
+  StringsNotEqual,
+};
+
+template <typename F>
+inline TestResult test_vals(const char *fmt, uint64_t num, int prec,
+                            int width) {
+  typename LIBC_NAMESPACE::fixed_point::FXRep<F>::StorageType raw_num = num;
+
+  long double ld_num = 0.0L;
+  long double ld_fract = 0.0L;
+
+  auto raw_num_bits = LIBC_NAMESPACE::fixed_point::FXBits<F>(raw_num);
+
+  // This needs to be a float with enough bits of precision to hold the fixed
+  // point number.
+  static_assert(sizeof(long double) > sizeof(long accum));
+
+  // build a long double that is equivalent to the fixed point number.
+  ld_num = static_cast<long double>(raw_num_bits.get_integral());
+  ld_fract = static_cast<long double>(raw_num_bits.get_fraction()) /
+             static_cast<long double>(1ll << raw_num_bits.get_exponent());
+
+  ld_num = ld_num + ld_fract;
+
+  if (raw_num_bits.get_sign()) {
+    ld_num = -ld_num;
+  }
+
+  // Call snprintf on a nullptr to get the buffer size.
+  int buffer_size = LIBC_NAMESPACE::snprintf(nullptr, 0, fmt, width, prec, num);
+
+  if (buffer_size < 0) {
+    return TestResult::BufferSizeFailed;
+  }
----------------
michaelrj-google wrote:

linking the docs every time feels rude to me. I'd prefer if you just said "these braces are unnecessary". We both know I'm not going to actually click on the link every time.

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


More information about the llvm-commits mailing list