Reorganize and cleanup tests
This commit is contained in:
parent
ea452bd33c
commit
fac1bc782d
36 changed files with 1780 additions and 1592 deletions
|
|
@ -2,10 +2,16 @@ from __future__ import print_function
|
|||
import sys
|
||||
import os
|
||||
import unittest
|
||||
import subprocess
|
||||
import llvm
|
||||
|
||||
tests = []
|
||||
|
||||
# Isolated tests
|
||||
# Tests that affect process-wide settings
|
||||
isolated_tests = []
|
||||
|
||||
|
||||
def run(verbosity=1):
|
||||
print('llvmpy is installed in: ' + os.path.dirname(__file__))
|
||||
print('llvmpy version: ' + llvm.__version__)
|
||||
|
|
@ -24,8 +30,24 @@ def run(verbosity=1):
|
|||
|
||||
# The default stream fails in IPython qtconsole on Windows,
|
||||
# so just using sys.stdout
|
||||
runner = unittest.TextTestRunner(verbosity=verbosity, stream=sys.stdout)
|
||||
return runner.run(suite)
|
||||
|
||||
kwargs = dict(verbosity=verbosity, stream=sys.stdout)
|
||||
|
||||
if sys.version_info[:2] > (2, 6):
|
||||
kwargs['buffer'] = True
|
||||
runner = unittest.TextTestRunner(**kwargs)
|
||||
testresult = runner.run(suite)
|
||||
|
||||
if testresult:
|
||||
# Run isolated tests
|
||||
print("run isolated tests".center(80, '-'))
|
||||
|
||||
for test in isolated_tests:
|
||||
print(('testing %s' % test).center(80))
|
||||
subprocess.check_call([sys.executable, '-m', test])
|
||||
|
||||
return testresult
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
|||
34
llvm/tests/support.py
Normal file
34
llvm/tests/support.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import sys
|
||||
import unittest
|
||||
import contextlib
|
||||
from llvm.tests import tests, isolated_tests # re-expose symbol
|
||||
|
||||
IS_PY3K = sys.version_info[0] >= 3
|
||||
BITS = tuple.__itemsize__ * 8
|
||||
|
||||
if sys.version_info[:2] <= (2, 6):
|
||||
# create custom TestCase
|
||||
class TestCase(unittest.TestCase):
|
||||
def assertIn(self, item, container):
|
||||
self.assertTrue(item in container)
|
||||
|
||||
def assertNotIn(self, item, container):
|
||||
self.assertFalse(item in container)
|
||||
|
||||
def assertLess(self, a, b):
|
||||
self.assertTrue(a < b)
|
||||
|
||||
def assertIs(self, a, b):
|
||||
self.assertTrue(a is b)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def assertRaises(self, exc):
|
||||
try:
|
||||
yield
|
||||
except exc:
|
||||
pass
|
||||
else:
|
||||
raise self.failureException("Did not raise %s" % exc)
|
||||
|
||||
else:
|
||||
TestCase = unittest.TestCase
|
||||
24
llvm/tests/test_arg_attr.py
Normal file
24
llvm/tests/test_arg_attr.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import unittest
|
||||
from llvm.core import Module, Type
|
||||
import llvm.core as lc
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestArgAttr(TestCase):
|
||||
def test_arg_attr(self):
|
||||
m = Module.new('oifjda')
|
||||
vptr = Type.pointer(Type.float())
|
||||
fnty = Type.function(Type.void(), [vptr] * 5)
|
||||
func = m.add_function(fnty, 'foo')
|
||||
attrs = [lc.ATTR_STRUCT_RET, lc.ATTR_BY_VAL, lc.ATTR_NEST,
|
||||
lc.ATTR_NO_ALIAS, lc.ATTR_NO_CAPTURE]
|
||||
for i, attr in enumerate(attrs):
|
||||
arg = func.args[i]
|
||||
self.assertEqual(i, arg.arg_no)
|
||||
arg.add_attribute(attr)
|
||||
self.assertTrue(attr in func.args[i])
|
||||
|
||||
tests.append(TestArgAttr)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
74
llvm/tests/test_arith.py
Normal file
74
llvm/tests/test_arith.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import unittest
|
||||
import llvm
|
||||
from llvm.core import (Module, Type, Builder)
|
||||
from llvm.ee import EngineBuilder
|
||||
from .support import TestCase, tests, BITS
|
||||
|
||||
class TestArith(TestCase):
|
||||
'''
|
||||
Test basic arithmetic support with LLVM MCJIT
|
||||
'''
|
||||
def func_template(self, ty, op):
|
||||
m = Module.new('dofjaa')
|
||||
fnty = Type.function(ty, [ty, ty])
|
||||
fn = m.add_function(fnty, 'foo')
|
||||
bldr = Builder.new(fn.append_basic_block(''))
|
||||
bldr.ret(getattr(bldr, op)(*fn.args))
|
||||
|
||||
engine = EngineBuilder.new(m).mcjit(True).create()
|
||||
ptr = engine.get_pointer_to_function(fn)
|
||||
|
||||
from ctypes import c_uint32, c_uint64, c_float, c_double, CFUNCTYPE
|
||||
|
||||
maptypes = {
|
||||
Type.int(32): c_uint32,
|
||||
Type.int(64): c_uint64,
|
||||
Type.float(): c_float,
|
||||
Type.double(): c_double,
|
||||
}
|
||||
cty = maptypes[ty]
|
||||
prototype = CFUNCTYPE(*[cty] * 3)
|
||||
callee = prototype(ptr)
|
||||
callee(12, 23)
|
||||
|
||||
def template(self, iop, fop):
|
||||
inttys = [Type.int(32), Type.int(64)]
|
||||
flttys = [Type.float(), Type.double()]
|
||||
|
||||
if iop:
|
||||
for ty in inttys:
|
||||
self.func_template(ty, iop)
|
||||
if fop:
|
||||
for ty in flttys:
|
||||
self.func_template(ty, fop)
|
||||
|
||||
def test_add(self):
|
||||
self.template('add', 'fadd')
|
||||
|
||||
def test_sub(self):
|
||||
self.template('sub', 'fsub')
|
||||
|
||||
def test_mul(self):
|
||||
self.template('mul', 'fmul')
|
||||
|
||||
def test_div(self):
|
||||
if BITS == 32:
|
||||
print('skipped test for div')
|
||||
print('known failure due to unresolved external symbol __udivdi3')
|
||||
return
|
||||
self.template('udiv', None) # 'fdiv')
|
||||
|
||||
def test_rem(self):
|
||||
if BITS == 32:
|
||||
print('skipped test for rem')
|
||||
print('known failure due to unresolved external symbol __umoddi3')
|
||||
return
|
||||
self.template('urem', None) # 'frem')
|
||||
|
||||
if llvm.version >= (3, 3):
|
||||
# MCJIT is broken in 3.2
|
||||
tests.append(TestArith)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
58
llvm/tests/test_asm.py
Normal file
58
llvm/tests/test_asm.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import os
|
||||
import unittest
|
||||
import tempfile
|
||||
import shutil
|
||||
from llvm.core import Module, Type
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestAsm(TestCase):
|
||||
def setUp(self):
|
||||
self.tmpdir = tempfile.mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
def test_asm(self):
|
||||
# create a module
|
||||
m = Module.new('module1')
|
||||
m.add_global_variable(Type.int(), 'i')
|
||||
|
||||
# write it's assembly representation to a file
|
||||
asm = str(m)
|
||||
|
||||
testasm_ll = os.path.join(self.tmpdir, 'testasm.ll')
|
||||
with open(testasm_ll, "w") as fout:
|
||||
fout.write(asm)
|
||||
|
||||
# read it back into a module
|
||||
with open(testasm_ll) as fin:
|
||||
m2 = Module.from_assembly(fin)
|
||||
# The default `m.id` is '<string>'.
|
||||
m2.id = m.id # Copy the name from `m`
|
||||
|
||||
self.assertEqual(str(m2).strip(), asm.strip())
|
||||
|
||||
def test_bitcode(self):
|
||||
# create a module
|
||||
m = Module.new('module1')
|
||||
m.add_global_variable(Type.int(), 'i')
|
||||
|
||||
# write it's assembly representation to a file
|
||||
asm = str(m)
|
||||
|
||||
testasm_bc = os.path.join(self.tmpdir, 'testasm.bc')
|
||||
with open(testasm_bc, "wb") as fout:
|
||||
m.to_bitcode(fout)
|
||||
|
||||
# read it back into a module
|
||||
with open(testasm_bc, "rb") as fin:
|
||||
m2 = Module.from_bitcode(fin)
|
||||
# The default `m.id` is '<string>'.
|
||||
m2.id = m.id # Copy the name from `m`
|
||||
|
||||
self.assertEqual(str(m2).strip(), asm.strip())
|
||||
|
||||
tests.append(TestAsm)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
85
llvm/tests/test_atomic.py
Normal file
85
llvm/tests/test_atomic.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Builder, Constant)
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestAtomic(TestCase):
|
||||
orderings = ['unordered', 'monotonic', 'acquire',
|
||||
'release', 'acq_rel', 'seq_cst']
|
||||
|
||||
atomic_op = ['xchg', 'add', 'sub', 'and', 'nand', 'or', 'xor',
|
||||
'max', 'min', 'umax', 'umin']
|
||||
|
||||
def test_atomic_cmpxchg(self):
|
||||
mod = Module.new('mod')
|
||||
functype = Type.function(Type.void(), [])
|
||||
func = mod.add_function(functype, name='foo')
|
||||
bb = func.append_basic_block('entry')
|
||||
bldr = Builder.new(bb)
|
||||
ptr = bldr.alloca(Type.int())
|
||||
|
||||
old = bldr.load(ptr)
|
||||
new = Constant.int(Type.int(), 1234)
|
||||
|
||||
for ordering in self.orderings:
|
||||
inst = bldr.atomic_cmpxchg(ptr, old, new, ordering)
|
||||
self.assertEqual(ordering, str(inst).strip().split(' ')[-1])
|
||||
|
||||
inst = bldr.atomic_cmpxchg(ptr, old, new, ordering, crossthread=False)
|
||||
self.assertEqual('singlethread', str(inst).strip().split(' ')[-2])
|
||||
|
||||
def test_atomic_rmw(self):
|
||||
mod = Module.new('mod')
|
||||
functype = Type.function(Type.void(), [])
|
||||
func = mod.add_function(functype, name='foo')
|
||||
bb = func.append_basic_block('entry')
|
||||
bldr = Builder.new(bb)
|
||||
ptr = bldr.alloca(Type.int())
|
||||
|
||||
val = Constant.int(Type.int(), 1234)
|
||||
|
||||
for ordering in self.orderings:
|
||||
inst = bldr.atomic_rmw('xchg', ptr, val, ordering)
|
||||
self.assertEqual(ordering, str(inst).split(' ')[-1])
|
||||
|
||||
for op in self.atomic_op:
|
||||
inst = bldr.atomic_rmw(op, ptr, val, ordering)
|
||||
self.assertEqual(op, str(inst).strip().split(' ')[3])
|
||||
|
||||
inst = bldr.atomic_rmw('xchg', ptr, val, ordering, crossthread=False)
|
||||
self.assertEqual('singlethread', str(inst).strip().split(' ')[-2])
|
||||
|
||||
for op in self.atomic_op:
|
||||
atomic_op = getattr(bldr, 'atomic_%s' % op)
|
||||
inst = atomic_op(ptr, val, ordering)
|
||||
self.assertEqual(op, str(inst).strip().split(' ')[3])
|
||||
|
||||
def test_atomic_ldst(self):
|
||||
mod = Module.new('mod')
|
||||
functype = Type.function(Type.void(), [])
|
||||
func = mod.add_function(functype, name='foo')
|
||||
bb = func.append_basic_block('entry')
|
||||
bldr = Builder.new(bb)
|
||||
ptr = bldr.alloca(Type.int())
|
||||
|
||||
for ordering in self.orderings:
|
||||
loaded = bldr.atomic_load(ptr, ordering)
|
||||
self.assert_('load atomic' in str(loaded))
|
||||
self.assertEqual(ordering,
|
||||
str(loaded).strip().split(' ')[-3].rstrip(','))
|
||||
self.assert_('align 1' in str(loaded))
|
||||
|
||||
stored = bldr.atomic_store(loaded, ptr, ordering)
|
||||
self.assert_('store atomic' in str(stored))
|
||||
self.assertEqual(ordering,
|
||||
str(stored).strip().split(' ')[-3].rstrip(','))
|
||||
self.assert_('align 1' in str(stored))
|
||||
|
||||
fenced = bldr.fence(ordering)
|
||||
self.assertEqual(['fence', ordering],
|
||||
str(fenced).strip().split(' '))
|
||||
|
||||
tests.append(TestAtomic)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
33
llvm/tests/test_attr.py
Normal file
33
llvm/tests/test_attr.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import unittest
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
from llvm.core import Module
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestAttr(TestCase):
|
||||
def make_module(self):
|
||||
test_module = """
|
||||
define void @sum(i32*, i32*) {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
"""
|
||||
buf = StringIO(test_module)
|
||||
return Module.from_assembly(buf)
|
||||
|
||||
def test_align(self):
|
||||
m = self.make_module()
|
||||
f = m.get_function_named('sum')
|
||||
f.args[0].alignment = 16
|
||||
self.assert_("align 16" in str(f))
|
||||
self.assertEqual(f.args[0].alignment, 16)
|
||||
|
||||
tests.append(TestAttr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
26
llvm/tests/test_cmp.py
Normal file
26
llvm/tests/test_cmp.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Builder, Constant)
|
||||
import llvm.core as lc
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestCmp(TestCase):
|
||||
def test_arg_attr(self):
|
||||
m = Module.new('oifjda')
|
||||
fnty = Type.function(Type.void(), [Type.int()])
|
||||
func = m.add_function(fnty, 'foo')
|
||||
bb = func.append_basic_block('')
|
||||
bldr = Builder.new(bb)
|
||||
|
||||
cmpinst = bldr.icmp(lc.ICMP_ULE, func.args[0],
|
||||
Constant.int(Type.int(), 123))
|
||||
self.assertTrue(repr(cmpinst.predicate).startswith('ICMP_ULE'))
|
||||
self.assertEqual(cmpinst.predicate, lc.ICMP_ULE)
|
||||
bldr.ret_void()
|
||||
|
||||
func.verify()
|
||||
|
||||
tests.append(TestCmp)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
23
llvm/tests/test_const_expr.py
Normal file
23
llvm/tests/test_const_expr.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Builder, Constant)
|
||||
import llvm.core as lc
|
||||
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestConstExpr(TestCase):
|
||||
|
||||
def test_constexpr_opcode(self):
|
||||
mod = Module.new('test_constexpr_opcode')
|
||||
func = mod.add_function(Type.function(Type.void(), []), name="foo")
|
||||
builder = Builder.new(func.append_basic_block('entry'))
|
||||
a = builder.inttoptr(Constant.int(Type.int(), 123),
|
||||
Type.pointer(Type.int()))
|
||||
self.assertTrue(isinstance(a, lc.ConstantExpr))
|
||||
self.assertEqual(a.opcode, lc.OPCODE_INTTOPTR)
|
||||
self.assertEqual(a.opcode_name, "inttoptr")
|
||||
|
||||
tests.append(TestConstExpr)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
90
llvm/tests/test_cpu_support.py
Normal file
90
llvm/tests/test_cpu_support.py
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import unittest
|
||||
import math
|
||||
from llvm.core import (Module, Type, Function, Builder,
|
||||
Constant)
|
||||
from llvm.ee import EngineBuilder
|
||||
import llvm.core as lc
|
||||
import llvm.ee as le
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestCPUSupport(TestCase):
|
||||
|
||||
def _build_test_module(self):
|
||||
mod = Module.new('test')
|
||||
|
||||
float = Type.double()
|
||||
mysinty = Type.function( float, [float] )
|
||||
mysin = mod.add_function(mysinty, "mysin")
|
||||
block = mysin.append_basic_block("entry")
|
||||
b = Builder.new(block)
|
||||
|
||||
sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float])
|
||||
pow = Function.intrinsic(mod, lc.INTR_POWI, [float])
|
||||
cos = Function.intrinsic(mod, lc.INTR_COS, [float])
|
||||
|
||||
mysin.args[0].name = "x"
|
||||
x = mysin.args[0]
|
||||
one = Constant.real(float, "1")
|
||||
cosx = b.call(cos, [x], "cosx")
|
||||
cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2")
|
||||
onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub
|
||||
sin = b.call(sqrt, [onemc2], "sin")
|
||||
b.ret(sin)
|
||||
return mod, mysin
|
||||
|
||||
def _template(self, mattrs):
|
||||
mod, func = self._build_test_module()
|
||||
ee = self._build_engine(mod, mattrs=mattrs)
|
||||
arg = le.GenericValue.real(Type.double(), 1.234)
|
||||
retval = ee.run_function(func, [arg])
|
||||
|
||||
golden = math.sin(1.234)
|
||||
answer = retval.as_real(Type.double())
|
||||
self.assertTrue(abs(answer-golden)/golden < 1e-5)
|
||||
|
||||
|
||||
def _build_engine(self, mod, mattrs):
|
||||
if mattrs:
|
||||
return EngineBuilder.new(mod).mattrs(mattrs).create()
|
||||
else:
|
||||
return EngineBuilder.new(mod).create()
|
||||
|
||||
def test_cpu_support2(self):
|
||||
features = 'sse3', 'sse41', 'sse42', 'avx'
|
||||
mattrs = ','.join(map(lambda s: '-%s' % s, features))
|
||||
print('disable mattrs', mattrs)
|
||||
self._template(mattrs)
|
||||
|
||||
def test_cpu_support3(self):
|
||||
features = 'sse41', 'sse42', 'avx'
|
||||
mattrs = ','.join(map(lambda s: '-%s' % s, features))
|
||||
print('disable mattrs', mattrs)
|
||||
self._template(mattrs)
|
||||
|
||||
def test_cpu_support4(self):
|
||||
features = 'sse42', 'avx'
|
||||
mattrs = ','.join(map(lambda s: '-%s' % s, features))
|
||||
print('disable mattrs', mattrs)
|
||||
self._template(mattrs)
|
||||
|
||||
def test_cpu_support5(self):
|
||||
features = 'avx',
|
||||
mattrs = ','.join(map(lambda s: '-%s' % s, features))
|
||||
print('disable mattrs', mattrs)
|
||||
self._template(mattrs)
|
||||
|
||||
def test_cpu_support6(self):
|
||||
features = []
|
||||
from llvm.workaround.avx_support import detect_avx_support
|
||||
if not detect_avx_support():
|
||||
print('Skipping: no AVX')
|
||||
else:
|
||||
mattrs = ','.join(map(lambda s: '-%s' % s, features))
|
||||
print('disable mattrs', mattrs)
|
||||
self._template(mattrs)
|
||||
|
||||
tests.append(TestCPUSupport)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
65
llvm/tests/test_engine_builder.py
Normal file
65
llvm/tests/test_engine_builder.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import unittest
|
||||
from llvm.core import Module, Type, Builder, Constant
|
||||
from llvm.ee import EngineBuilder
|
||||
import llvm.ee as le
|
||||
import llvmpy
|
||||
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestEngineBuilder(TestCase):
|
||||
|
||||
def make_test_module(self):
|
||||
module = Module.new("testmodule")
|
||||
fnty = Type.function(Type.int(), [])
|
||||
function = module.add_function(fnty, 'foo')
|
||||
bb_entry = function.append_basic_block('entry')
|
||||
builder = Builder.new(bb_entry)
|
||||
builder.ret(Constant.int(Type.int(), 0xcafe))
|
||||
module.verify()
|
||||
return module
|
||||
|
||||
def run_foo(self, ee, module):
|
||||
function = module.get_function_named('foo')
|
||||
retval = ee.run_function(function, [])
|
||||
self.assertEqual(retval.as_int(), 0xcafe)
|
||||
|
||||
|
||||
def test_enginebuilder_basic(self):
|
||||
module = self.make_test_module()
|
||||
self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr))
|
||||
ee = EngineBuilder.new(module).create()
|
||||
self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr))
|
||||
self.run_foo(ee, module)
|
||||
|
||||
|
||||
def test_enginebuilder_with_tm(self):
|
||||
tm = le.TargetMachine.new()
|
||||
module = self.make_test_module()
|
||||
self.assertTrue(llvmpy.capsule.has_ownership(module._ptr._ptr))
|
||||
ee = EngineBuilder.new(module).create(tm)
|
||||
self.assertFalse(llvmpy.capsule.has_ownership(module._ptr._ptr))
|
||||
self.run_foo(ee, module)
|
||||
|
||||
def test_enginebuilder_force_jit(self):
|
||||
module = self.make_test_module()
|
||||
ee = EngineBuilder.new(module).force_jit().create()
|
||||
|
||||
self.run_foo(ee, module)
|
||||
#
|
||||
# def test_enginebuilder_force_interpreter(self):
|
||||
# module = self.make_test_module()
|
||||
# ee = EngineBuilder.new(module).force_interpreter().create()
|
||||
#
|
||||
# self.run_foo(ee, module)
|
||||
|
||||
def test_enginebuilder_opt(self):
|
||||
module = self.make_test_module()
|
||||
ee = EngineBuilder.new(module).opt(3).create()
|
||||
|
||||
self.run_foo(ee, module)
|
||||
|
||||
tests.append(TestEngineBuilder)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
37
llvm/tests/test_exact.py
Normal file
37
llvm/tests/test_exact.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Builder)
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestExact(TestCase):
|
||||
def make_module(self):
|
||||
mod = Module.new('asdfa')
|
||||
fnty = Type.function(Type.void(), [Type.int()] * 2)
|
||||
func = mod.add_function(fnty, 'foo')
|
||||
bldr = Builder.new(func.append_basic_block(''))
|
||||
return mod, func, bldr
|
||||
|
||||
def has_exact(self, inst, op):
|
||||
self.assertTrue(('%s exact' % op) in str(inst), "exact flag does not work")
|
||||
|
||||
def _test_template(self, opf, opname):
|
||||
mod, func, bldr = self.make_module()
|
||||
a, b = func.args
|
||||
self.has_exact(opf(bldr, a, b, exact=True), opname)
|
||||
|
||||
def test_udiv_exact(self):
|
||||
self._test_template(Builder.udiv, 'udiv')
|
||||
|
||||
def test_sdiv_exact(self):
|
||||
self._test_template(Builder.sdiv, 'sdiv')
|
||||
|
||||
def test_lshr_exact(self):
|
||||
self._test_template(Builder.lshr, 'lshr')
|
||||
|
||||
def test_ashr_exact(self):
|
||||
self._test_template(Builder.ashr, 'ashr')
|
||||
|
||||
tests.append(TestExact)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
47
llvm/tests/test_execution_engine.py
Normal file
47
llvm/tests/test_execution_engine.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import unittest
|
||||
from llvm.core import Type
|
||||
import llvm.core as lc
|
||||
import llvm.ee as le
|
||||
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestExecutionEngine(TestCase):
|
||||
def test_get_pointer_to_global(self):
|
||||
module = lc.Module.new(str(self))
|
||||
gvar = module.add_global_variable(Type.int(), 'hello')
|
||||
X = 1234
|
||||
gvar.initializer = lc.Constant.int(Type.int(), X)
|
||||
|
||||
ee = le.ExecutionEngine.new(module)
|
||||
ptr = ee.get_pointer_to_global(gvar)
|
||||
from ctypes import c_void_p, cast, c_int, POINTER
|
||||
casted = cast(c_void_p(ptr), POINTER(c_int))
|
||||
self.assertEqual(X, casted[0])
|
||||
|
||||
def test_add_global_mapping(self):
|
||||
module = lc.Module.new(str(self))
|
||||
gvar = module.add_global_variable(Type.int(), 'hello')
|
||||
|
||||
fnty = lc.Type.function(Type.int(), [])
|
||||
foo = module.add_function(fnty, name='foo')
|
||||
bldr = lc.Builder.new(foo.append_basic_block('entry'))
|
||||
bldr.ret(bldr.load(gvar))
|
||||
|
||||
ee = le.ExecutionEngine.new(module)
|
||||
from ctypes import c_int, addressof, CFUNCTYPE
|
||||
value = 0xABCD
|
||||
value_ctype = c_int(value)
|
||||
value_pointer = addressof(value_ctype)
|
||||
|
||||
ee.add_global_mapping(gvar, value_pointer)
|
||||
|
||||
foo_addr = ee.get_pointer_to_function(foo)
|
||||
prototype = CFUNCTYPE(c_int)
|
||||
foo_callable = prototype(foo_addr)
|
||||
self.assertEqual(foo_callable(), value)
|
||||
|
||||
tests.append(TestExecutionEngine)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
34
llvm/tests/test_inlining.py
Normal file
34
llvm/tests/test_inlining.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Builder, Constant, inline_function)
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestInlining(TestCase):
|
||||
def test_inline_call(self):
|
||||
mod = Module.new(__name__)
|
||||
callee = mod.add_function(Type.function(Type.int(), [Type.int()]),
|
||||
name='bar')
|
||||
|
||||
builder = Builder.new(callee.append_basic_block('entry'))
|
||||
builder.ret(builder.add(callee.args[0], callee.args[0]))
|
||||
|
||||
caller = mod.add_function(Type.function(Type.int(), []),
|
||||
name='foo')
|
||||
|
||||
builder = Builder.new(caller.append_basic_block('entry'))
|
||||
callinst = builder.call(callee, [Constant.int(Type.int(), 1234)])
|
||||
builder.ret(callinst)
|
||||
|
||||
pre_inlining = str(caller)
|
||||
self.assertIn('call', pre_inlining)
|
||||
|
||||
self.assertTrue(inline_function(callinst))
|
||||
|
||||
post_inlining = str(caller)
|
||||
self.assertNotIn('call', post_inlining)
|
||||
self.assertIn('2468', post_inlining)
|
||||
|
||||
tests.append(TestInlining)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
113
llvm/tests/test_intrinsic.py
Normal file
113
llvm/tests/test_intrinsic.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import unittest
|
||||
import sys
|
||||
import math
|
||||
from llvm.core import (Module, Type, Function, Builder, Constant)
|
||||
import llvm.core as lc
|
||||
import llvm.ee as le
|
||||
from .support import TestCase, tests, BITS
|
||||
|
||||
class TestIntrinsic(TestCase):
|
||||
def test_bswap(self):
|
||||
# setup a function and a builder
|
||||
mod = Module.new('test')
|
||||
functy = Type.function(Type.int(), [])
|
||||
func = mod.add_function(functy, "showme")
|
||||
block = func.append_basic_block("entry")
|
||||
b = Builder.new(block)
|
||||
|
||||
# let's do bswap on a 32-bit integer using llvm.bswap
|
||||
val = Constant.int(Type.int(), 0x42)
|
||||
bswap = Function.intrinsic(mod, lc.INTR_BSWAP, [Type.int()])
|
||||
|
||||
bswap_res = b.call(bswap, [val])
|
||||
b.ret(bswap_res)
|
||||
|
||||
# logging.debug(mod)
|
||||
|
||||
# the output is:
|
||||
#
|
||||
# ; ModuleID = 'test'
|
||||
#
|
||||
# define void @showme() {
|
||||
# entry:
|
||||
# %0 = call i32 @llvm.bswap.i32(i32 42)
|
||||
# ret i32 %0
|
||||
# }
|
||||
|
||||
# let's run the function
|
||||
ee = le.ExecutionEngine.new(mod)
|
||||
retval = ee.run_function(func, [])
|
||||
self.assertEqual(retval.as_int(), 0x42000000)
|
||||
|
||||
def test_mysin(self):
|
||||
if sys.platform == 'win32' and BITS == 32:
|
||||
# float32 support is known to fail on 32-bit Windows
|
||||
return
|
||||
|
||||
# mysin(x) = sqrt(1.0 - pow(cos(x), 2))
|
||||
mod = Module.new('test')
|
||||
|
||||
float = Type.float()
|
||||
mysinty = Type.function( float, [float] )
|
||||
mysin = mod.add_function(mysinty, "mysin")
|
||||
block = mysin.append_basic_block("entry")
|
||||
b = Builder.new(block)
|
||||
|
||||
sqrt = Function.intrinsic(mod, lc.INTR_SQRT, [float])
|
||||
pow = Function.intrinsic(mod, lc.INTR_POWI, [float])
|
||||
cos = Function.intrinsic(mod, lc.INTR_COS, [float])
|
||||
|
||||
mysin.args[0].name = "x"
|
||||
x = mysin.args[0]
|
||||
one = Constant.real(float, "1")
|
||||
cosx = b.call(cos, [x], "cosx")
|
||||
cos2 = b.call(pow, [cosx, Constant.int(Type.int(), 2)], "cos2")
|
||||
onemc2 = b.fsub(one, cos2, "onemc2") # Should use fsub
|
||||
sin = b.call(sqrt, [onemc2], "sin")
|
||||
b.ret(sin)
|
||||
#logging.debug(mod)
|
||||
|
||||
# ; ModuleID = 'test'
|
||||
#
|
||||
# define void @showme() {
|
||||
# entry:
|
||||
# call i32 @llvm.bswap.i32( i32 42 ) ; <i32>:0 [#uses
|
||||
# }
|
||||
#
|
||||
# declare i32 @llvm.bswap.i32(i32) nounwind readnone
|
||||
#
|
||||
# define float @mysin(float %x) {
|
||||
# entry:
|
||||
# %cosx = call float @llvm.cos.f32( float %x ) ; <float
|
||||
# %cos2 = call float @llvm.powi.f32( float %cosx, i32 2 )
|
||||
# %onemc2 = sub float 1.000000e+00, %cos2 ; <float> [#uses
|
||||
# %sin = call float @llvm.sqrt.f32( float %onemc2 )
|
||||
# ret float %sin
|
||||
# }
|
||||
#
|
||||
# declare float @llvm.sqrt.f32(float) nounwind readnone
|
||||
#
|
||||
# declare float @llvm.powi.f32(float, i32) nounwind readnone
|
||||
#
|
||||
# declare float @llvm.cos.f32(float) nounwind readnone
|
||||
|
||||
# let's run the function
|
||||
|
||||
from llvm.workaround.avx_support import detect_avx_support
|
||||
if not detect_avx_support():
|
||||
ee = le.EngineBuilder.new(mod).mattrs("-avx").create()
|
||||
else:
|
||||
ee = le.EngineBuilder.new(mod).create()
|
||||
|
||||
arg = le.GenericValue.real(Type.float(), 1.234)
|
||||
retval = ee.run_function(mysin, [arg])
|
||||
|
||||
golden = math.sin(1.234)
|
||||
answer = retval.as_real(Type.float())
|
||||
self.assertTrue(abs(answer-golden)/golden < 1e-5)
|
||||
|
||||
tests.append(TestIntrinsic)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
99
llvm/tests/test_intrinsic_basic.py
Normal file
99
llvm/tests/test_intrinsic_basic.py
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import unittest
|
||||
import sys
|
||||
import math
|
||||
from llvm.core import (Module, Type, Function, Builder)
|
||||
import llvm.core as lc
|
||||
import llvm.ee as le
|
||||
from .support import TestCase, BITS, tests
|
||||
|
||||
class TestIntrinsicBasic(TestCase):
|
||||
|
||||
def _build_module(self, float):
|
||||
mod = Module.new('test')
|
||||
functy = Type.function(float, [float])
|
||||
func = mod.add_function(functy, "mytest%s" % float)
|
||||
block = func.append_basic_block("entry")
|
||||
b = Builder.new(block)
|
||||
return mod, func, b
|
||||
|
||||
def _template(self, mod, func, pyfunc):
|
||||
float = func.type.pointee.return_type
|
||||
|
||||
from llvm.workaround.avx_support import detect_avx_support
|
||||
if not detect_avx_support():
|
||||
ee = le.EngineBuilder.new(mod).mattrs("-avx").create()
|
||||
else:
|
||||
ee = le.EngineBuilder.new(mod).create()
|
||||
arg = le.GenericValue.real(float, 1.234)
|
||||
retval = ee.run_function(func, [arg])
|
||||
golden = pyfunc(1.234)
|
||||
answer = retval.as_real(float)
|
||||
self.assertTrue(abs(answer - golden) / golden < 1e-7)
|
||||
|
||||
def test_sqrt_f32(self):
|
||||
float = Type.float()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_SQRT, [float])
|
||||
b.ret(b.call(intr, func.args))
|
||||
self._template(mod, func, math.sqrt)
|
||||
|
||||
def test_sqrt_f64(self):
|
||||
float = Type.double()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_SQRT, [float])
|
||||
b.ret(b.call(intr, func.args))
|
||||
self._template(mod, func, math.sqrt)
|
||||
|
||||
def test_cos_f32(self):
|
||||
if sys.platform == 'win32' and BITS == 32:
|
||||
# float32 support is known to fail on 32-bit Windows
|
||||
return
|
||||
float = Type.float()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_COS, [float])
|
||||
b.ret(b.call(intr, func.args))
|
||||
self._template(mod, func, math.cos)
|
||||
|
||||
def test_cos_f64(self):
|
||||
float = Type.double()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_COS, [float])
|
||||
b.ret(b.call(intr, func.args))
|
||||
self._template(mod, func, math.cos)
|
||||
|
||||
def test_sin_f32(self):
|
||||
if sys.platform == 'win32' and BITS == 32:
|
||||
# float32 support is known to fail on 32-bit Windows
|
||||
return
|
||||
float = Type.float()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_SIN, [float])
|
||||
b.ret(b.call(intr, func.args))
|
||||
self._template(mod, func, math.sin)
|
||||
|
||||
def test_sin_f64(self):
|
||||
float = Type.double()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_SIN, [float])
|
||||
b.ret(b.call(intr, func.args))
|
||||
self._template(mod, func, math.sin)
|
||||
|
||||
def test_powi_f32(self):
|
||||
float = Type.float()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_POWI, [float])
|
||||
b.ret(b.call(intr, [func.args[0], lc.Constant.int(Type.int(), 2)]))
|
||||
self._template(mod, func, lambda x: x**2)
|
||||
|
||||
def test_powi_f64(self):
|
||||
float = Type.double()
|
||||
mod, func, b = self._build_module(float)
|
||||
intr = Function.intrinsic(mod, lc.INTR_POWI, [float])
|
||||
b.ret(b.call(intr, [func.args[0], lc.Constant.int(Type.int(), 2)]))
|
||||
self._template(mod, func, lambda x: x**2)
|
||||
|
||||
tests.append(TestIntrinsicBasic)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
26
llvm/tests/test_issue_10.py
Normal file
26
llvm/tests/test_issue_10.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Builder)
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestIssue10(TestCase):
|
||||
def test_issue10(self):
|
||||
m = Module.new('a')
|
||||
ti = Type.int()
|
||||
tf = Type.function(ti, [ti, ti])
|
||||
|
||||
f = m.add_function(tf, "func1")
|
||||
|
||||
bb = f.append_basic_block('entry')
|
||||
|
||||
b = Builder.new(bb)
|
||||
|
||||
# There are no instructions in bb. Positioning of the
|
||||
# builder at beginning (or end) should succeed (trivially).
|
||||
b.position_at_end(bb)
|
||||
b.position_at_beginning(bb)
|
||||
|
||||
tests.append(TestIssue10)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
34
llvm/tests/test_llrt.py
Normal file
34
llvm/tests/test_llrt.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import unittest
|
||||
import llvm.core as lc
|
||||
import llvm.ee as le
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestLLRT(TestCase):
|
||||
def test_llrt_divmod(self):
|
||||
from llvm import llrt
|
||||
m = lc.Module.new('testllrt')
|
||||
longlong = lc.Type.int(64)
|
||||
lfunc = m.add_function(lc.Type.function(longlong, [longlong, longlong]), 'foo')
|
||||
bldr = lc.Builder.new(lfunc.append_basic_block(''))
|
||||
bldr.ret(bldr.udiv(*lfunc.args))
|
||||
|
||||
llrt.replace_divmod64(lfunc)
|
||||
|
||||
rt = llrt.LLRT()
|
||||
rt.install_symbols()
|
||||
|
||||
engine = le.EngineBuilder.new(m).create()
|
||||
pointer = engine.get_pointer_to_function(lfunc)
|
||||
|
||||
from ctypes import CFUNCTYPE, c_uint64
|
||||
func = CFUNCTYPE(c_uint64, c_uint64, c_uint64)(pointer)
|
||||
a, b = 98342, 2231
|
||||
self.assertEqual(func(98342, 2231), 98342 // 2231)
|
||||
|
||||
rt.uninstall_symbols()
|
||||
|
||||
tests.append(TestLLRT)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
File diff suppressed because it is too large
Load diff
73
llvm/tests/test_mcjit.py
Normal file
73
llvm/tests/test_mcjit.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import unittest
|
||||
import sys
|
||||
import llvm
|
||||
from llvm.core import (Module, Type, Builder)
|
||||
from llvm.ee import EngineBuilder
|
||||
|
||||
import llvm.ee as le
|
||||
from .support import TestCase, tests, BITS
|
||||
|
||||
class TestMCJIT(TestCase):
|
||||
def test_mcjit(self):
|
||||
m = Module.new('oidfjs')
|
||||
fnty = Type.function(Type.int(), [Type.int(), Type.int()])
|
||||
func = m.add_function(fnty, 'foo')
|
||||
bb = func.append_basic_block('')
|
||||
bldr = Builder.new(bb)
|
||||
bldr.ret(bldr.add(*func.args))
|
||||
|
||||
func.verify()
|
||||
|
||||
engine = EngineBuilder.new(m).mcjit(True).create()
|
||||
ptr = engine.get_pointer_to_function(func)
|
||||
|
||||
from ctypes import c_int, CFUNCTYPE
|
||||
callee = CFUNCTYPE(c_int, c_int, c_int)(ptr)
|
||||
self.assertEqual(321 + 123, callee(321, 123))
|
||||
|
||||
def test_multi_module_linking(self):
|
||||
# generate external library module
|
||||
m = Module.new('external-library-module')
|
||||
fnty = Type.function(Type.int(), [Type.int(), Type.int()])
|
||||
libfname = 'myadd'
|
||||
func = m.add_function(fnty, libfname)
|
||||
bb = func.append_basic_block('')
|
||||
bldr = Builder.new(bb)
|
||||
bldr.ret(bldr.add(*func.args))
|
||||
func.verify()
|
||||
|
||||
# JIT the lib module and bind dynamic symbol
|
||||
libengine = EngineBuilder.new(m).mcjit(True).create()
|
||||
myadd_ptr = libengine.get_pointer_to_function(func)
|
||||
le.dylib_add_symbol(libfname, myadd_ptr)
|
||||
|
||||
# reference external library
|
||||
m = Module.new('user')
|
||||
fnty = Type.function(Type.int(), [Type.int(), Type.int()])
|
||||
func = m.add_function(fnty, 'foo')
|
||||
bb = func.append_basic_block('')
|
||||
bldr = Builder.new(bb)
|
||||
extadd = m.get_or_insert_function(fnty, name=libfname)
|
||||
bldr.ret(bldr.call(extadd, func.args))
|
||||
func.verify()
|
||||
|
||||
# JIT the user module
|
||||
engine = EngineBuilder.new(m).mcjit(True).create()
|
||||
ptr = engine.get_pointer_to_function(func)
|
||||
self.assertEqual(myadd_ptr,
|
||||
engine.get_pointer_to_named_function(libfname))
|
||||
|
||||
from ctypes import c_int, CFUNCTYPE
|
||||
callee = CFUNCTYPE(c_int, c_int, c_int)(ptr)
|
||||
self.assertEqual(321 + 123, callee(321, 123))
|
||||
|
||||
|
||||
if (llvm.version >= (3, 3) and
|
||||
not (sys.platform.startswith('win32') and BITS == 64)):
|
||||
# MCJIT broken in 3.2, the test will segfault in OSX?
|
||||
# Compatbility problem on windows 7 64-bit?
|
||||
tests.append(TestMCJIT)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
25
llvm/tests/test_metadata.py
Normal file
25
llvm/tests/test_metadata.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Constant, MetaData, MetaDataString)
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestMetaData(TestCase):
|
||||
# test module metadata
|
||||
def test_metadata(self):
|
||||
m = Module.new('a')
|
||||
t = Type.int()
|
||||
metadata = MetaData.get(m, [Constant.int(t, 100),
|
||||
MetaDataString.get(m, 'abcdef'),
|
||||
None])
|
||||
MetaData.add_named_operand(m, 'foo', metadata)
|
||||
self.assertEqual(MetaData.get_named_operands(m, 'foo'), [metadata])
|
||||
self.assertEqual(MetaData.get_named_operands(m, 'bar'), [])
|
||||
self.assertEqual(len(metadata.operands), 3)
|
||||
self.assertEqual(metadata.operands[0].z_ext_value, 100)
|
||||
self.assertEqual(metadata.operands[1].string, 'abcdef')
|
||||
self.assertTrue(metadata.operands[2] is None)
|
||||
|
||||
tests.append(TestMetaData)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
20
llvm/tests/test_named_metadata.py
Normal file
20
llvm/tests/test_named_metadata.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Constant, MetaData)
|
||||
from .support import TestCase, tests
|
||||
|
||||
|
||||
class TestNamedMetaData(TestCase):
|
||||
def test_named_md(self):
|
||||
m = Module.new('test_named_md')
|
||||
nmd = m.get_or_insert_named_metadata('something')
|
||||
md = MetaData.get(m, [Constant.int(Type.int(), 0xbeef)])
|
||||
nmd.add(md)
|
||||
self.assertTrue(str(nmd).startswith('!something'))
|
||||
ir = str(m)
|
||||
self.assertTrue('!something' in ir)
|
||||
|
||||
tests.append(TestNamedMetaData)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
81
llvm/tests/test_native.py
Normal file
81
llvm/tests/test_native.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import unittest
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from distutils.spawn import find_executable
|
||||
from llvm.core import (Module, Type, Builder, Constant)
|
||||
from .support import TestCase, IS_PY3K, tests
|
||||
|
||||
class TestNative(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.tmpdir = tempfile.mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.tmpdir)
|
||||
|
||||
|
||||
def _make_module(self):
|
||||
m = Module.new('module1')
|
||||
m.add_global_variable(Type.int(), 'i')
|
||||
|
||||
fty = Type.function(Type.int(), [])
|
||||
f = m.add_function(fty, name='main')
|
||||
|
||||
bldr = Builder.new(f.append_basic_block('entry'))
|
||||
bldr.ret(Constant.int(Type.int(), 0xab))
|
||||
|
||||
return m
|
||||
|
||||
def _compile(self, src):
|
||||
cc = find_executable('cc')
|
||||
if not cc:
|
||||
return
|
||||
|
||||
dst = os.path.join(self.tmpdir, 'llvmobj.out')
|
||||
s = subprocess.call([cc, '-o', dst, src])
|
||||
if s != 0:
|
||||
raise Exception("Cannot compile")
|
||||
|
||||
s = subprocess.call([dst])
|
||||
self.assertEqual(s, 0xab)
|
||||
|
||||
def test_assembly(self):
|
||||
if sys.platform == 'darwin':
|
||||
# skip this test on MacOSX for now
|
||||
return
|
||||
|
||||
m = self._make_module()
|
||||
output = m.to_native_assembly()
|
||||
|
||||
src = os.path.join(self.tmpdir, 'llvmasm.s')
|
||||
with open(src, 'wb') as fout:
|
||||
if IS_PY3K:
|
||||
fout.write(output.encode('utf-8'))
|
||||
else:
|
||||
fout.write(output)
|
||||
|
||||
self._compile(src)
|
||||
|
||||
def test_object(self):
|
||||
if sys.platform == 'darwin':
|
||||
# skip this test on MacOSX for now
|
||||
return
|
||||
|
||||
m = self._make_module()
|
||||
output = m.to_native_object()
|
||||
|
||||
src = os.path.join(self.tmpdir, 'llvmobj.o')
|
||||
with open(src, 'wb') as fout:
|
||||
fout.write(output)
|
||||
|
||||
self._compile(src)
|
||||
|
||||
if sys.platform != 'win32':
|
||||
tests.append(TestNative)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
48
llvm/tests/test_nuw_nsw.py
Normal file
48
llvm/tests/test_nuw_nsw.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import unittest
|
||||
from llvm.core import Module, Type, Builder
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestNUWNSW(TestCase):
|
||||
def make_module(self):
|
||||
mod = Module.new('asdfa')
|
||||
fnty = Type.function(Type.void(), [Type.int()] * 2)
|
||||
func = mod.add_function(fnty, 'foo')
|
||||
bldr = Builder.new(func.append_basic_block(''))
|
||||
return mod, func, bldr
|
||||
|
||||
def has_nsw(self, inst, op):
|
||||
self.assertTrue(('%s nsw' % op) in str(inst), "NSW flag does not work")
|
||||
|
||||
def has_nuw(self, inst, op):
|
||||
self.assertTrue(('%s nuw' % op) in str(inst), "NUW flag does not work")
|
||||
|
||||
def _test_template(self, opf, opname):
|
||||
mod, func, bldr = self.make_module()
|
||||
a, b = func.args
|
||||
self.has_nsw(opf(bldr, a, b, nsw=True), opname)
|
||||
self.has_nuw(opf(bldr, a, b, nuw=True), opname)
|
||||
|
||||
def test_add_nuw_nsw(self):
|
||||
self._test_template(Builder.add, 'add')
|
||||
|
||||
def test_sub_nuw_nsw(self):
|
||||
self._test_template(Builder.sub, 'sub')
|
||||
|
||||
def test_mul_nuw_nsw(self):
|
||||
self._test_template(Builder.mul, 'mul')
|
||||
|
||||
def test_shl_nuw_nsw(self):
|
||||
self._test_template(Builder.shl, 'shl')
|
||||
|
||||
def test_neg_nuw_nsw(self):
|
||||
mod, func, bldr = self.make_module()
|
||||
a, b = func.args
|
||||
self.has_nsw(bldr.neg(a, nsw=True), 'sub')
|
||||
self.has_nuw(bldr.neg(a, nuw=True), 'sub')
|
||||
|
||||
|
||||
tests.append(TestNUWNSW)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
107
llvm/tests/test_obj_cache.py
Normal file
107
llvm/tests/test_obj_cache.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import unittest
|
||||
from llvm.core import Module, Type, GlobalVariable, Function, Builder
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestObjCache(TestCase):
|
||||
|
||||
def test_objcache(self):
|
||||
# Testing module aliasing
|
||||
m1 = Module.new('a')
|
||||
t = Type.int()
|
||||
ft = Type.function(t, [t])
|
||||
f1 = m1.add_function(ft, "func")
|
||||
m2 = f1.module
|
||||
self.assert_(m1 is m2)
|
||||
|
||||
# Testing global vairable aliasing 1
|
||||
gv1 = GlobalVariable.new(m1, t, "gv")
|
||||
gv2 = GlobalVariable.get(m1, "gv")
|
||||
self.assert_(gv1 is gv2)
|
||||
|
||||
# Testing global vairable aliasing 2
|
||||
gv3 = m1.global_variables[0]
|
||||
self.assert_(gv1 is gv3)
|
||||
|
||||
# Testing global vairable aliasing 3
|
||||
gv2 = None
|
||||
gv3 = None
|
||||
|
||||
gv1.delete()
|
||||
|
||||
gv4 = GlobalVariable.new(m1, t, "gv")
|
||||
|
||||
self.assert_(gv1 is not gv4)
|
||||
|
||||
# Testing function aliasing 1
|
||||
b1 = f1.append_basic_block('entry')
|
||||
f2 = b1.function
|
||||
self.assert_(f1 is f2)
|
||||
|
||||
# Testing function aliasing 2
|
||||
f3 = m1.get_function_named("func")
|
||||
self.assert_(f1 is f3)
|
||||
|
||||
# Testing function aliasing 3
|
||||
f4 = Function.get_or_insert(m1, ft, "func")
|
||||
self.assert_(f1 is f4)
|
||||
|
||||
# Testing function aliasing 4
|
||||
f5 = Function.get(m1, "func")
|
||||
self.assert_(f1 is f5)
|
||||
|
||||
# Testing function aliasing 5
|
||||
f6 = m1.get_or_insert_function(ft, "func")
|
||||
self.assert_(f1 is f6)
|
||||
|
||||
# Testing function aliasing 6
|
||||
f7 = m1.functions[0]
|
||||
self.assert_(f1 is f7)
|
||||
|
||||
# Testing argument aliasing
|
||||
a1 = f1.args[0]
|
||||
a2 = f1.args[0]
|
||||
self.assert_(a1 is a2)
|
||||
|
||||
# Testing basic block aliasing 1
|
||||
b2 = f1.basic_blocks[0]
|
||||
self.assert_(b1 is b2)
|
||||
|
||||
# Testing basic block aliasing 2
|
||||
b3 = f1.entry_basic_block
|
||||
self.assert_(b1 is b3)
|
||||
|
||||
# Testing basic block aliasing 3
|
||||
b31 = f1.entry_basic_block
|
||||
self.assert_(b1 is b31)
|
||||
|
||||
# Testing basic block aliasing 4
|
||||
bldr = Builder.new(b1)
|
||||
b4 = bldr.basic_block
|
||||
self.assert_(b1 is b4)
|
||||
|
||||
# Testing basic block aliasing 5
|
||||
i1 = bldr.ret_void()
|
||||
b5 = i1.basic_block
|
||||
self.assert_(b1 is b5)
|
||||
|
||||
# Testing instruction aliasing 1
|
||||
i2 = b5.instructions[0]
|
||||
self.assert_(i1 is i2)
|
||||
|
||||
# phi node
|
||||
phi = bldr.phi(t)
|
||||
phi.add_incoming(f1.args[0], b1)
|
||||
v2 = phi.get_incoming_value(0)
|
||||
b6 = phi.get_incoming_block(0)
|
||||
|
||||
# Testing PHI / basic block aliasing 5
|
||||
self.assert_(b1 is b6)
|
||||
|
||||
# Testing PHI / value aliasing
|
||||
self.assert_(f1.args[0] is v2)
|
||||
|
||||
tests.append(TestObjCache)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
38
llvm/tests/test_opaque.py
Normal file
38
llvm/tests/test_opaque.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import unittest
|
||||
import llvm
|
||||
from llvm.core import Type
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestOpaque(TestCase):
|
||||
|
||||
def test_opaque(self):
|
||||
# Create an opaque type
|
||||
ts = Type.opaque('mystruct')
|
||||
self.assertTrue('type opaque' in str(ts))
|
||||
self.assertTrue(ts.is_opaque)
|
||||
self.assertTrue(ts.is_identified)
|
||||
self.assertFalse(ts.is_literal)
|
||||
#print(ts)
|
||||
|
||||
# Create a recursive type
|
||||
ts.set_body([Type.int(), Type.pointer(ts)])
|
||||
|
||||
self.assertEqual(ts.elements[0], Type.int())
|
||||
self.assertEqual(ts.elements[1], Type.pointer(ts))
|
||||
self.assertEqual(ts.elements[1].pointee, ts)
|
||||
self.assertFalse(ts.is_opaque) # is not longer a opaque type
|
||||
#print(ts)
|
||||
|
||||
with self.assertRaises(llvm.LLVMException):
|
||||
# Cannot redefine
|
||||
ts.set_body([])
|
||||
|
||||
def test_opaque_with_no_name(self):
|
||||
with self.assertRaises(llvm.LLVMException):
|
||||
Type.opaque('')
|
||||
|
||||
tests.append(TestOpaque)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
66
llvm/tests/test_operands.py
Normal file
66
llvm/tests/test_operands.py
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import unittest
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
from llvm.core import Module
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestOperands(TestCase):
|
||||
# implement a test function
|
||||
test_module = """
|
||||
define i32 @prod(i32, i32) {
|
||||
entry:
|
||||
%2 = mul i32 %0, %1
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
define i32 @test_func(i32, i32, i32) {
|
||||
entry:
|
||||
%tmp1 = call i32 @prod(i32 %0, i32 %1)
|
||||
%tmp2 = add i32 %tmp1, %2
|
||||
%tmp3 = add i32 %tmp2, 1
|
||||
%tmp4 = add i32 %tmp3, -1
|
||||
%tmp5 = add i64 -81985529216486895, 12297829382473034410
|
||||
ret i32 %tmp4
|
||||
}
|
||||
"""
|
||||
def test_operands(self):
|
||||
m = Module.from_assembly(StringIO(self.test_module))
|
||||
|
||||
test_func = m.get_function_named("test_func")
|
||||
prod = m.get_function_named("prod")
|
||||
|
||||
# test operands
|
||||
i1 = test_func.basic_blocks[0].instructions[0]
|
||||
i2 = test_func.basic_blocks[0].instructions[1]
|
||||
i3 = test_func.basic_blocks[0].instructions[2]
|
||||
i4 = test_func.basic_blocks[0].instructions[3]
|
||||
i5 = test_func.basic_blocks[0].instructions[4]
|
||||
|
||||
self.assertEqual(i1.operand_count, 3)
|
||||
self.assertEqual(i2.operand_count, 2)
|
||||
|
||||
self.assertEqual(i3.operands[1].z_ext_value, 1)
|
||||
self.assertEqual(i3.operands[1].s_ext_value, 1)
|
||||
self.assertEqual(i4.operands[1].z_ext_value, 0xffffffff)
|
||||
self.assertEqual(i4.operands[1].s_ext_value, -1)
|
||||
self.assertEqual(i5.operands[0].s_ext_value, -81985529216486895)
|
||||
self.assertEqual(i5.operands[1].z_ext_value, 12297829382473034410)
|
||||
|
||||
self.assert_(i1.operands[-1] is prod)
|
||||
self.assert_(i1.operands[0] is test_func.args[0])
|
||||
self.assert_(i1.operands[1] is test_func.args[1])
|
||||
self.assert_(i2.operands[0] is i1)
|
||||
self.assert_(i2.operands[1] is test_func.args[2])
|
||||
self.assertEqual(len(i1.operands), 3)
|
||||
self.assertEqual(len(i2.operands), 2)
|
||||
|
||||
self.assert_(i1.called_function is prod)
|
||||
|
||||
tests.append(TestOperands)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
143
llvm/tests/test_passes.py
Normal file
143
llvm/tests/test_passes.py
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
import unittest
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
import llvm
|
||||
from llvm.core import Module
|
||||
import llvm.passes as lp
|
||||
import llvm.ee as le
|
||||
from .support import TestCase, tests
|
||||
|
||||
|
||||
class TestPasses(TestCase):
|
||||
# Create a module.
|
||||
asm = """
|
||||
|
||||
define i32 @test() nounwind {
|
||||
ret i32 42
|
||||
}
|
||||
|
||||
define i32 @test1() nounwind {
|
||||
entry:
|
||||
%tmp = alloca i32
|
||||
store i32 42, i32* %tmp, align 4
|
||||
%tmp1 = load i32* %tmp, align 4
|
||||
%tmp2 = call i32 @test()
|
||||
%tmp3 = load i32* %tmp, align 4
|
||||
%tmp4 = load i32* %tmp, align 4
|
||||
ret i32 %tmp1
|
||||
}
|
||||
|
||||
define i32 @test2() nounwind {
|
||||
entry:
|
||||
%tmp = call i32 @test()
|
||||
ret i32 %tmp
|
||||
}
|
||||
"""
|
||||
def test_passes(self):
|
||||
m = Module.from_assembly(StringIO(self.asm))
|
||||
|
||||
fn_test1 = m.get_function_named('test1')
|
||||
fn_test2 = m.get_function_named('test2')
|
||||
|
||||
original_test1 = str(fn_test1)
|
||||
original_test2 = str(fn_test2)
|
||||
|
||||
# Let's run a module-level inlining pass. First, create a pass manager.
|
||||
pm = lp.PassManager.new()
|
||||
|
||||
# Add the target data as the first "pass". This is mandatory.
|
||||
pm.add(le.TargetData.new(''))
|
||||
|
||||
# Add the inlining pass.
|
||||
pm.add(lp.PASS_INLINE)
|
||||
|
||||
# Run it!
|
||||
pm.run(m)
|
||||
|
||||
# Done with the pass manager.
|
||||
del pm
|
||||
|
||||
# Make sure test2 is inlined
|
||||
self.assertNotEqual(str(fn_test2).strip(), original_test2.strip())
|
||||
|
||||
bb_entry = fn_test2.basic_blocks[0]
|
||||
|
||||
self.assertEqual(len(bb_entry.instructions), 1)
|
||||
self.assertEqual(bb_entry.instructions[0].opcode_name, 'ret')
|
||||
|
||||
# Let's run a DCE pass on the the function 'test1' now. First create a
|
||||
# function pass manager.
|
||||
fpm = lp.FunctionPassManager.new(m)
|
||||
|
||||
# Add the target data as first "pass". This is mandatory.
|
||||
fpm.add(le.TargetData.new(''))
|
||||
|
||||
# Add a DCE pass
|
||||
fpm.add(lp.PASS_ADCE)
|
||||
|
||||
# Run the pass on the function 'test1'
|
||||
fpm.run(m.get_function_named('test1'))
|
||||
|
||||
# Make sure test1 is modified
|
||||
self.assertNotEqual(str(fn_test1).strip(), original_test1.strip())
|
||||
|
||||
def test_passes_with_pmb(self):
|
||||
m = Module.from_assembly(StringIO(self.asm))
|
||||
|
||||
fn_test1 = m.get_function_named('test1')
|
||||
fn_test2 = m.get_function_named('test2')
|
||||
|
||||
original_test1 = str(fn_test1)
|
||||
original_test2 = str(fn_test2)
|
||||
|
||||
# Try out the PassManagerBuilder
|
||||
|
||||
pmb = lp.PassManagerBuilder.new()
|
||||
|
||||
self.assertEqual(pmb.opt_level, 2) # ensure default is level 2
|
||||
pmb.opt_level = 3
|
||||
self.assertEqual(pmb.opt_level, 3) # make sure it works
|
||||
|
||||
self.assertEqual(pmb.size_level, 0) # ensure default is level 0
|
||||
pmb.size_level = 2
|
||||
self.assertEqual(pmb.size_level, 2) # make sure it works
|
||||
|
||||
self.assertFalse(pmb.vectorize) # ensure default is False
|
||||
pmb.vectorize = True
|
||||
self.assertTrue(pmb.vectorize) # make sure it works
|
||||
|
||||
# make sure the default is False
|
||||
self.assertFalse(pmb.disable_unit_at_a_time)
|
||||
self.assertFalse(pmb.disable_unroll_loops)
|
||||
if llvm.version <= (3, 3):
|
||||
self.assertFalse(pmb.disable_simplify_lib_calls)
|
||||
|
||||
pmb.disable_unit_at_a_time = True
|
||||
self.assertTrue(pmb.disable_unit_at_a_time)
|
||||
|
||||
# Do function pass
|
||||
fpm = lp.FunctionPassManager.new(m)
|
||||
pmb.populate(fpm)
|
||||
fpm.run(fn_test1)
|
||||
|
||||
# Make sure test1 has changed
|
||||
self.assertNotEqual(str(fn_test1).strip(), original_test1.strip())
|
||||
|
||||
# Do module pass
|
||||
pm = lp.PassManager.new()
|
||||
pmb.populate(pm)
|
||||
pm.run(m)
|
||||
|
||||
# Make sure test2 has changed
|
||||
self.assertNotEqual(str(fn_test2).strip(), original_test2.strip())
|
||||
|
||||
def test_dump_passes(self):
|
||||
self.assertTrue(len(lp.PASSES)>0, msg="Cannot have no passes")
|
||||
|
||||
tests.append(TestPasses)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
15
llvm/tests/test_struct.py
Normal file
15
llvm/tests/test_struct.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import unittest
|
||||
from llvm.core import Type
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestStruct(TestCase):
|
||||
def test_struct_identical(self):
|
||||
ta = Type.struct([Type.int(32), Type.float()], name='ta')
|
||||
tb = Type.struct([Type.int(32), Type.float()])
|
||||
self.assertTrue(ta.is_layout_identical(tb))
|
||||
|
||||
tests.append(TestStruct)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ class TestStructSystemVABI(unittest.TestCase, FloatTestMixin):
|
|||
'''
|
||||
Non microsoft convention
|
||||
'''
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# 64 bits
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ class TestStructSystemVABI(unittest.TestCase, FloatTestMixin):
|
|||
@skip_if_not_64bits
|
||||
def test_two_halfwords(self):
|
||||
'''Arguments smaller or equal to a word is packed into a word.
|
||||
|
||||
|
||||
Passing as struct { float, float } occupies two XMM registers instead
|
||||
of one.
|
||||
The output must be in XMM.
|
||||
|
|
@ -267,7 +267,7 @@ class TestStructSystemVABI(unittest.TestCase, FloatTestMixin):
|
|||
self.assertClose(arg.x / arg.y, ret.y)
|
||||
self.assertEqual(arg.z, ret.z)
|
||||
|
||||
|
||||
|
||||
@skip_if_not_32bits
|
||||
def test_structure_abi_32_2(self):
|
||||
'''x86 is simple. Always pass structure as memory.
|
||||
|
|
@ -378,7 +378,7 @@ class TestStructMicrosoftABI(unittest.TestCase, FloatTestMixin):
|
|||
'''
|
||||
Microsoft convention
|
||||
'''
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# 64 bits
|
||||
|
||||
|
|
@ -488,7 +488,7 @@ class TestStructMicrosoftABI(unittest.TestCase, FloatTestMixin):
|
|||
@skip_if_not_64bits
|
||||
def test_two_halfwords(self):
|
||||
'''Arguments smaller or equal to a word is packed into a word.
|
||||
|
||||
|
||||
Floats structure are not passed on the XMM.
|
||||
Treat it as a i64.
|
||||
'''
|
||||
|
|
@ -603,7 +603,7 @@ class TestStructMicrosoftABI(unittest.TestCase, FloatTestMixin):
|
|||
|
||||
float_type = lc.Type.float()
|
||||
struct_type = lc.Type.struct([float_type, float_type])
|
||||
struct_ptr_type = lc.Type.pointer(struct_type)
|
||||
|
||||
abi_type = lc.Type.int(64)
|
||||
func_type = lc.Type.function(abi_type, [struct_type])
|
||||
func = m.add_function(func_type, name='foo')
|
||||
|
|
|
|||
36
llvm/tests/test_switch.py
Normal file
36
llvm/tests/test_switch.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import unittest
|
||||
from llvm.core import (Module, Type, Builder, Constant)
|
||||
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestSwitch(TestCase):
|
||||
def test_arg_attr(self):
|
||||
m = Module.new('oifjda')
|
||||
fnty = Type.function(Type.void(), [Type.int()])
|
||||
func = m.add_function(fnty, 'foo')
|
||||
bb = func.append_basic_block('')
|
||||
bbdef = func.append_basic_block('')
|
||||
bbsw1 = func.append_basic_block('')
|
||||
bbsw2 = func.append_basic_block('')
|
||||
bldr = Builder.new(bb)
|
||||
|
||||
swt = bldr.switch(func.args[0], bbdef, n=2)
|
||||
swt.add_case(Constant.int(Type.int(), 0), bbsw1)
|
||||
swt.add_case(Constant.int(Type.int(), 1), bbsw2)
|
||||
|
||||
bldr.position_at_end(bbsw1)
|
||||
bldr.ret_void()
|
||||
|
||||
bldr.position_at_end(bbsw2)
|
||||
bldr.ret_void()
|
||||
|
||||
bldr.position_at_end(bbdef)
|
||||
bldr.ret_void()
|
||||
|
||||
func.verify()
|
||||
|
||||
tests.append(TestSwitch)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
62
llvm/tests/test_target_machines.py
Normal file
62
llvm/tests/test_target_machines.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import unittest
|
||||
import llvm.core as lc
|
||||
import llvm.ee as le
|
||||
from llvm.core import Type, Builder
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestTargetMachines(TestCase):
|
||||
'''Exercise target machines
|
||||
|
||||
Require PTX backend
|
||||
'''
|
||||
def test_native(self):
|
||||
m, _ = self._build_module()
|
||||
tm = le.EngineBuilder.new(m).select_target()
|
||||
|
||||
self.assertTrue(tm.target_name)
|
||||
self.assertTrue(tm.target_data)
|
||||
self.assertTrue(tm.target_short_description)
|
||||
self.assertTrue(tm.triple)
|
||||
self.assertIn('foo', tm.emit_assembly(m))
|
||||
self.assertTrue(le.get_host_cpu_name())
|
||||
|
||||
def test_ptx(self):
|
||||
if le.initialize_target('PTX', noraise=True):
|
||||
arch = 'ptx64'
|
||||
elif le.initialize_target('NVPTX', noraise=True):
|
||||
arch = 'nvptx64'
|
||||
else:
|
||||
return # skip this test
|
||||
|
||||
print(arch)
|
||||
m, func = self._build_module()
|
||||
func.calling_convention = lc.CC_PTX_KERNEL # set calling conv
|
||||
ptxtm = le.TargetMachine.lookup(arch=arch, cpu='sm_20')
|
||||
self.assertTrue(ptxtm.triple)
|
||||
self.assertTrue(ptxtm.cpu)
|
||||
ptxasm = ptxtm.emit_assembly(m)
|
||||
self.assertIn('foo', ptxasm)
|
||||
if arch == 'nvptx64':
|
||||
self.assertIn('.address_size 64', ptxasm)
|
||||
self.assertIn('sm_20', ptxasm)
|
||||
|
||||
def _build_module(self):
|
||||
m = lc.Module.new('TestTargetMachines')
|
||||
|
||||
fnty = Type.function(Type.void(), [])
|
||||
func = m.add_function(fnty, name='foo')
|
||||
|
||||
bldr = Builder.new(func.append_basic_block('entry'))
|
||||
bldr.ret_void()
|
||||
m.verify()
|
||||
return m, func
|
||||
|
||||
def _build_bad_archname(self):
|
||||
with self.assertRaises(RuntimeError):
|
||||
le.TargetMachine.lookup("ain't no arch name")
|
||||
|
||||
tests.append(TestTargetMachines)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
30
llvm/tests/test_type_hash.py
Normal file
30
llvm/tests/test_type_hash.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import unittest
|
||||
from llvm.core import Type
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestTypeHash(TestCase):
|
||||
def test_scalar_type(self):
|
||||
i32a = Type.int(32)
|
||||
i32b = Type.int(32)
|
||||
i64a = Type.int(64)
|
||||
i64b = Type.int(64)
|
||||
ts = set([i32a, i32b, i64a, i64b])
|
||||
self.assertTrue(len(ts))
|
||||
self.assertTrue(i32a in ts)
|
||||
self.assertTrue(i64b in ts)
|
||||
|
||||
def test_struct_type(self):
|
||||
ta = Type.struct([Type.int(32), Type.float()])
|
||||
tb = Type.struct([Type.int(32), Type.float()])
|
||||
tc = Type.struct([Type.int(32), Type.int(32), Type.float()])
|
||||
ts = set([ta, tb, tc])
|
||||
self.assertTrue(len(ts) == 2)
|
||||
self.assertTrue(ta in ts)
|
||||
self.assertTrue(tb in ts)
|
||||
self.assertTrue(tc in ts)
|
||||
|
||||
tests.append(TestTypeHash)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
43
llvm/tests/test_uses.py
Normal file
43
llvm/tests/test_uses.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import unittest
|
||||
from llvm.core import Module, Type, Builder, Constant
|
||||
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestUses(TestCase):
|
||||
|
||||
def test_uses(self):
|
||||
m = Module.new('a')
|
||||
t = Type.int()
|
||||
ft = Type.function(t, [t, t, t])
|
||||
f = m.add_function(ft, "func")
|
||||
b = f.append_basic_block('entry')
|
||||
bld = Builder.new(b)
|
||||
tmp1 = bld.add(Constant.int(t, 100), f.args[0], "tmp1")
|
||||
tmp2 = bld.add(tmp1, f.args[1], "tmp2")
|
||||
tmp3 = bld.add(tmp1, f.args[2], "tmp3")
|
||||
bld.ret(tmp3)
|
||||
|
||||
# Testing use count
|
||||
self.assertEqual(f.args[0].use_count, 1)
|
||||
self.assertEqual(f.args[1].use_count, 1)
|
||||
self.assertEqual(f.args[2].use_count, 1)
|
||||
self.assertEqual(tmp1.use_count, 2)
|
||||
self.assertEqual(tmp2.use_count, 0)
|
||||
self.assertEqual(tmp3.use_count, 1)
|
||||
|
||||
# Testing uses
|
||||
self.assert_(f.args[0].uses[0] is tmp1)
|
||||
self.assertEqual(len(f.args[0].uses), 1)
|
||||
self.assert_(f.args[1].uses[0] is tmp2)
|
||||
self.assertEqual(len(f.args[1].uses), 1)
|
||||
self.assert_(f.args[2].uses[0] is tmp3)
|
||||
self.assertEqual(len(f.args[2].uses), 1)
|
||||
self.assertEqual(len(tmp1.uses), 2)
|
||||
self.assertEqual(len(tmp2.uses), 0)
|
||||
self.assertEqual(len(tmp3.uses), 1)
|
||||
|
||||
tests.append(TestUses)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
59
llvm/tests/test_volatile.py
Normal file
59
llvm/tests/test_volatile.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import unittest
|
||||
from llvm.core import Module, Type, Builder
|
||||
from .support import TestCase, tests
|
||||
|
||||
class TestVolatile(TestCase):
|
||||
|
||||
def test_volatile(self):
|
||||
mod = Module.new('mod')
|
||||
functype = Type.function(Type.void(), [])
|
||||
func = mod.add_function(functype, name='foo')
|
||||
bb = func.append_basic_block('entry')
|
||||
bldr = Builder.new(bb)
|
||||
ptr = bldr.alloca(Type.int())
|
||||
|
||||
# test load inst
|
||||
val = bldr.load(ptr)
|
||||
self.assertFalse(val.is_volatile, "default must be non-volatile")
|
||||
val.set_volatile(True)
|
||||
self.assertTrue(val.is_volatile, "fail to set volatile")
|
||||
val.set_volatile(False)
|
||||
self.assertFalse(val.is_volatile, "fail to unset volatile")
|
||||
|
||||
# test store inst
|
||||
store_inst = bldr.store(val, ptr)
|
||||
self.assertFalse(store_inst.is_volatile, "default must be non-volatile")
|
||||
store_inst.set_volatile(True)
|
||||
self.assertTrue(store_inst.is_volatile, "fail to set volatile")
|
||||
store_inst.set_volatile(False)
|
||||
self.assertFalse(store_inst.is_volatile, "fail to unset volatile")
|
||||
|
||||
def test_volatile_another(self):
|
||||
mod = Module.new('mod')
|
||||
functype = Type.function(Type.void(), [])
|
||||
func = mod.add_function(functype, name='foo')
|
||||
bb = func.append_basic_block('entry')
|
||||
bldr = Builder.new(bb)
|
||||
ptr = bldr.alloca(Type.int())
|
||||
|
||||
# test load inst
|
||||
val = bldr.load(ptr, volatile=True)
|
||||
self.assertTrue(val.is_volatile, "volatile kwarg does not work")
|
||||
val.set_volatile(False)
|
||||
self.assertFalse(val.is_volatile, "fail to unset volatile")
|
||||
val.set_volatile(True)
|
||||
self.assertTrue(val.is_volatile, "fail to set volatile")
|
||||
|
||||
# test store inst
|
||||
store_inst = bldr.store(val, ptr, volatile=True)
|
||||
self.assertTrue(store_inst.is_volatile, "volatile kwarg does not work")
|
||||
store_inst.set_volatile(False)
|
||||
self.assertFalse(store_inst.is_volatile, "fail to unset volatile")
|
||||
store_inst.set_volatile(True)
|
||||
self.assertTrue(store_inst.is_volatile, "fail to set volatile")
|
||||
|
||||
tests.append(TestVolatile)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
3
setup.py
3
setup.py
|
|
@ -189,7 +189,8 @@ setup(
|
|||
'llpython',
|
||||
'llvm_array',
|
||||
'llvmpy.api', 'llvmpy.api.llvm',
|
||||
'llvm.tests'],
|
||||
'llvm.tests',
|
||||
'llvm.tests.isolated'],
|
||||
package_data = {'llvm': ['llrt/*.ll']},
|
||||
py_modules = ['llvmpy',
|
||||
'llvmpy._capsule',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue