LLVM 24.0.0git
MathExtras.cpp
Go to the documentation of this file.
1//===-- MathExtras.cpp - Implement the MathExtras header --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the MathExtras.h header
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/APInt.h"
15
16#ifdef _MSC_VER
17#include <limits>
18#else
19#include <cmath>
20#endif
21
22namespace llvm {
23
24#if defined(_MSC_VER)
25 // Visual Studio defines the HUGE_VAL class of macros using purposeful
26 // constant arithmetic overflow, which it then warns on when encountered.
27 const float huge_valf = std::numeric_limits<float>::infinity();
28#else
29 const float huge_valf = HUGE_VALF;
30#endif
31
32 /// Returns the number of digits in the given integer.
34 static constexpr struct ConstexprData {
35 uint8_t AtLeast[65] = {};
36 uint64_t Boundaries[20] = {};
37 static constexpr int NumDigitsConstexpr(uint64_t N) {
38 int res = 1;
39 while (N >= 10) {
40 res++;
41 N /= 10;
42 }
43 return res;
44 }
45 constexpr ConstexprData() {
46 uint64_t Val = ~0ull;
47 for (uint64_t i = 0; i <= 64; i++) {
48 uint64_t Digits = NumDigitsConstexpr(Val) - 1;
49 AtLeast[i] = Digits;
50 Val >>= 1;
51 }
52 // Special case because X=0 should return 1 and not 0
53 Boundaries[0] = 0;
54 Val = 10;
55 for (uint64_t i = 1; i < 20; i++) {
56 Boundaries[i] = Val;
57 Val *= 10;
58 }
59 }
60 } Data;
61
62 uint64_t Base2 = X ? countl_zero(X) : 64;
63 uint64_t Digits = Data.AtLeast[Base2];
64 return Digits + (X >= Data.Boundaries[Digits]);
65 }
66
67} // namespace llvm
68
70 assert(Z && "Division by zero");
71 bool Overflowed = false;
72 uint64_t Product = SaturatingMultiply(X, Y, &Overflowed);
73 if (!Overflowed)
74 return divideNearest(Product, Z);
75 // Adding Z / 2 before the division rounds half up, like divideNearest.
76 APInt WideProduct = APInt(128, X) * APInt(128, Y);
77 APInt Divisor(128, Z);
78 return (WideProduct + Divisor.lshr(1)).udiv(Divisor).getLimitedValue();
79}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
This file implements a class to represent arbitrary precision integral constant values and operations...
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
static InstructionCost divideNearest(InstructionCost Numerator, uint64_t Denominator)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Class for arbitrary precision integers.
Definition APInt.h:78
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:853
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI int NumDigitsBase10(uint64_t X)
Returns the number of digits in the given integer.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:263
LLVM_ABI const float huge_valf
Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiply(T X, T Y, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, of type T.
Definition MathExtras.h:638
LLVM_ABI uint64_t mulDivNearest(uint64_t X, uint64_t Y, uint64_t Z)
Returns (X * Y) / Z rounded by round-half-up, like divideNearest.
#define N