LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
APIntHelper.cpp
Go to the documentation of this file.
1//===-- APIntHelper.cpp - APInt helpers -------------------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
11
12namespace llzk {
13
14llvm::APSInt expandingAdd(llvm::APSInt lhs, llvm::APSInt rhs) {
15 lhs = safeToSigned(lhs), rhs = safeToSigned(rhs);
16 // +2: +1 for expansion, +1 to preserve the sign bit
17 unsigned requiredBits = std::max(lhs.getActiveBits(), rhs.getActiveBits()) + 2;
18 unsigned newBitwidth = std::max({requiredBits, lhs.getBitWidth(), rhs.getBitWidth()});
19 return lhs.extend(newBitwidth) + rhs.extend(newBitwidth);
20}
21
22llvm::APSInt expandingSub(llvm::APSInt lhs, llvm::APSInt rhs) {
23 lhs = safeToSigned(lhs), rhs = safeToSigned(rhs);
24 // +2: +1 for expansion, +1 to preserve the sign bit
25 unsigned requiredBits = std::max(lhs.getActiveBits(), rhs.getActiveBits()) + 2;
26 unsigned newBitwidth = std::max({requiredBits, lhs.getBitWidth(), rhs.getBitWidth()});
27 return lhs.extend(newBitwidth) - rhs.extend(newBitwidth);
28}
29
30llvm::APSInt expandingMul(llvm::APSInt lhs, llvm::APSInt rhs) {
31 lhs = safeToSigned(lhs), rhs = safeToSigned(rhs);
32 // +1 to preserve the sign bit
33 unsigned requiredBits = lhs.getActiveBits() + rhs.getActiveBits() + 1;
34 unsigned newBitwidth = std::max({requiredBits, lhs.getBitWidth(), rhs.getBitWidth()});
35 return lhs.extend(newBitwidth) * rhs.extend(newBitwidth);
36}
37
38llvm::APSInt safeToSigned(llvm::APSInt i) {
39 if (i.isSigned()) {
40 return i;
41 }
42 i = i.extend(i.getBitWidth() + 1);
43 i.setIsSigned(true);
44 return i;
45}
46
47std::strong_ordering safeCmp(llvm::APSInt lhs, llvm::APSInt rhs) {
48 lhs = safeToSigned(lhs), rhs = safeToSigned(rhs);
49 unsigned requiredBits = std::max(lhs.getBitWidth(), rhs.getBitWidth());
50 lhs = lhs.extend(requiredBits), rhs = rhs.extend(requiredBits);
51 if (lhs < rhs) {
52 return std::strong_ordering::less;
53 } else if (lhs > rhs) {
54 return std::strong_ordering::greater;
55 } else {
56 return std::strong_ordering::equal;
57 }
58}
59
60} // namespace llzk
This file defines helpers for manipulating APInts/APSInts for large numbers and operations over those...
llvm::APSInt safeToSigned(llvm::APSInt i)
Safely converts the given int to a signed int if it is an unsigned int by adding an extra bit for the...
std::strong_ordering safeCmp(llvm::APSInt lhs, llvm::APSInt rhs)
Compares lhs and rhs, regardless of the bitwidth of lhs and rhs.
llvm::APSInt expandingAdd(llvm::APSInt lhs, llvm::APSInt rhs)
Safely add lhs and rhs, expanding the width of the result as necessary.
llvm::APSInt expandingSub(llvm::APSInt lhs, llvm::APSInt rhs)
Safely subtract lhs and rhs, expanding the width of the result as necessary.
llvm::APSInt expandingMul(llvm::APSInt lhs, llvm::APSInt rhs)
Safely multiple lhs and rhs, expanding the width of the result as necessary.