Skip to content

Commit

Permalink
Add floating point rounding as an argument to get_constant_value
Browse files Browse the repository at this point in the history
  • Loading branch information
tbennun committed Jul 19, 2023
1 parent 1260f35 commit 8daa56a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
12 changes: 9 additions & 3 deletions docs/source/user-guide/binding/value-references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,14 @@ The ValueRef class

The value is a constant.

* .. method:: get_constant_value(self, signed=False)
* .. method:: get_constant_value(self, signed_int=False, round_fp=False)

Return the constant value, either as a literal (for example, int
or float) when supported, or as a string otherwise. If ``signed``
is True and the constant is an integer, returns a signed integer.
or float) when supported, or as a string otherwise. Keyword arguments
specify the preferences during conversion:

* If ``signed_int`` is True and the constant is an integer, returns a
signed integer.
* If ``round_fp`` True and the constant is a floating point value,
rounds the result upon accuracy loss (e.g., when querying an fp128
value). By default, raises an exception on accuracy loss.
14 changes: 9 additions & 5 deletions llvmlite/binding/value.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,15 +343,19 @@ def opcode(self):
% (self._kind,))
return ffi.ret_string(ffi.lib.LLVMPY_GetOpcodeName(self))

def get_constant_value(self, signed=False):
def get_constant_value(self, signed_int=False, round_fp=False):
"""
Return the constant value, either as a literal (when supported)
or as a string.
Parameters
-----------
signed : bool
signed_int : bool
if True and the constant is an integer, returns a signed version
round_fp : bool
if True and the constant is a floating point value, rounds the
result upon accuracy loss (e.g., when querying an fp128 value).
By default, raises an exception on accuracy loss
"""
if not self.is_constant:
raise ValueError('expected constant value, got %s'
Expand All @@ -367,14 +371,14 @@ def get_constant_value(self, signed=False):
return int.from_bytes(
asbytes,
('little' if little_endian.value else 'big'),
signed=signed,
signed=signed_int,
)
elif self.value_kind == ValueKind.constant_fp:
# Convert floating-point values to double (Python float)
# Convert floating-point values to double-precision (Python float)
accuracy_loss = c_bool(False)
value = ffi.lib.LLVMPY_GetConstantFPValue(self,
byref(accuracy_loss))
if accuracy_loss.value:
if accuracy_loss.value and not round_fp:
raise ValueError(
'Accuracy loss encountered in conversion of constant '
f'value {str(self)}')
Expand Down
7 changes: 4 additions & 3 deletions llvmlite/tests/test_binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def no_de_locale():
target triple = "{triple}"
define void @foo() {{
%const = fadd fp128 0xLF3CB1CCF26FBC178452FB4EC7F91DEAD, 0xLF3CB1CCF26FBC178452FB4EC7F91973F
%const = fadd fp128 0xLF3CB1CCF26FBC178452FB4EC7F91DEAD, 0xL00000000000000000000000000000001
ret void
}}
""" # noqa E501
Expand Down Expand Up @@ -1641,10 +1641,10 @@ def test_constant_int(self):
posint64 = list(insts[1].operands)[0]
negint64 = list(insts[2].operands)[0]
self.assertEqual(posint64.get_constant_value(), 5)
self.assertEqual(negint64.get_constant_value(signed=True), -5)
self.assertEqual(negint64.get_constant_value(signed_int=True), -5)

# Convert from unsigned arbitrary-precision integer to signed i64
as_u64 = negint64.get_constant_value(signed=False)
as_u64 = negint64.get_constant_value(signed_int=False)
as_i64 = int.from_bytes(as_u64.to_bytes(8, 'little'), 'little',
signed=True)
self.assertEqual(as_i64, -5)
Expand All @@ -1667,6 +1667,7 @@ def test_constant_fp(self):
operands = list(inst.operands)
with self.assertRaises(ValueError):
operands[0].get_constant_value()
self.assertAlmostEqual(operands[1].get_constant_value(round_fp=True), 0)

def test_constant_as_string(self):
mod = self.module(asm_null_constant)
Expand Down

0 comments on commit 8daa56a

Please sign in to comment.