181 lines
4.8 KiB
Python
181 lines
4.8 KiB
Python
from __future__ import print_function, absolute_import
|
|
import sys
|
|
from llvm.core import Type, Function, Builder, Module
|
|
import llvm.core as lc
|
|
import llvm.ee as le
|
|
import multiprocessing
|
|
from ctypes import *
|
|
|
|
INTRINSICS = {}
|
|
|
|
CTYPES_MAP = {
|
|
Type.int(): c_int32,
|
|
Type.int(64): c_int64,
|
|
Type.float(): c_float,
|
|
Type.double(): c_double,
|
|
}
|
|
|
|
|
|
def register(name, retty, *args):
|
|
def wrap(fn):
|
|
INTRINSICS[name] = (retty, args), fn
|
|
return fn
|
|
return wrap
|
|
|
|
|
|
def intr_impl(intrcode, *types):
|
|
def impl(module, builder, args):
|
|
intr = Function.intrinsic(module, intrcode, types)
|
|
r = builder.call(intr, args)
|
|
return r
|
|
return impl
|
|
|
|
|
|
register("llvm.powi.f64", Type.double(), Type.double(), Type.int())\
|
|
(intr_impl(lc.INTR_POWI, Type.double()))
|
|
|
|
register("llvm.powi.f32", Type.float(), Type.float(), Type.int())\
|
|
(intr_impl(lc.INTR_POWI, Type.float()))
|
|
|
|
register("llvm.pow.f64", Type.double(), Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_POW, Type.double()))
|
|
|
|
register("llvm.pow.f32", Type.float(), Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_POW, Type.float()))
|
|
|
|
register("llvm.sin.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_SIN, Type.double()))
|
|
|
|
register("llvm.sin.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_SIN, Type.float()))
|
|
|
|
register("llvm.cos.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_COS, Type.double()))
|
|
|
|
register("llvm.cos.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_COS, Type.float()))
|
|
|
|
register("llvm.log.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_LOG, Type.double()))
|
|
|
|
register("llvm.log.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_LOG, Type.float()))
|
|
|
|
register("llvm.log2.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_LOG2, Type.double()))
|
|
|
|
register("llvm.log2.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_LOG2, Type.float()))
|
|
|
|
register("llvm.log10.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_LOG10, Type.double()))
|
|
|
|
register("llvm.log10.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_LOG10, Type.float()))
|
|
|
|
register("llvm.sqrt.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_SQRT, Type.double()))
|
|
|
|
register("llvm.sqrt.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_SQRT, Type.float()))
|
|
|
|
register("llvm.exp.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_EXP, Type.double()))
|
|
|
|
register("llvm.exp.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_EXP, Type.float()))
|
|
|
|
register("llvm.exp2.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_EXP2, Type.double()))
|
|
|
|
register("llvm.exp2.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_EXP2, Type.float()))
|
|
|
|
register("llvm.fabs.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_FABS, Type.double()))
|
|
|
|
register("llvm.fabs.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_FABS, Type.float()))
|
|
|
|
register("llvm.floor.f64", Type.double(), Type.double())\
|
|
(intr_impl(lc.INTR_FLOOR, Type.double()))
|
|
|
|
register("llvm.floor.f32", Type.float(), Type.float())\
|
|
(intr_impl(lc.INTR_FLOOR, Type.float()))
|
|
|
|
|
|
def build_test(name):
|
|
(retty, args), impl = INTRINSICS[name]
|
|
module = Module.new("test.%s" % name)
|
|
fn = module.add_function(Type.function(retty, args), name="test_%s" % name)
|
|
builder = Builder.new(fn.append_basic_block(""))
|
|
retval = impl(module, builder, fn.args)
|
|
builder.ret(retval)
|
|
fn.verify()
|
|
module.verify()
|
|
return module, fn
|
|
|
|
|
|
def run_test(name):
|
|
module, fn = build_test(name)
|
|
eb = le.EngineBuilder.new(module).mcjit(True)
|
|
engine = eb.create()
|
|
ptr = engine.get_pointer_to_function(fn)
|
|
|
|
argtys = fn.type.pointee.args
|
|
retty = fn.type.pointee.return_type
|
|
cargtys = [CTYPES_MAP[a] for a in argtys]
|
|
cretty = CTYPES_MAP[retty]
|
|
cfunc = CFUNCTYPE(cretty, *cargtys)(ptr)
|
|
args = [1] * len(cargtys)
|
|
cfunc(*args)
|
|
|
|
|
|
def spawner(name):
|
|
print("Testing %s" % name)
|
|
proc = multiprocessing.Process(target=run_test, args=(name,))
|
|
|
|
print('-' * 80)
|
|
proc.start()
|
|
proc.join()
|
|
|
|
if proc.exitcode != 0:
|
|
print("FAILED")
|
|
ok = False
|
|
else:
|
|
print("PASSED")
|
|
ok = True
|
|
print('=' * 80)
|
|
print()
|
|
|
|
return ok
|
|
|
|
USAGE = """
|
|
Args: [name]
|
|
|
|
name: intrinsic name to test
|
|
|
|
If no name is given, test all intrinsics.
|
|
|
|
"""
|
|
|
|
|
|
def main(argv=()):
|
|
if len(argv) == 1:
|
|
intrname = argv[1]
|
|
spawner(intrname)
|
|
elif not argv:
|
|
failed = []
|
|
for name in sorted(INTRINSICS):
|
|
if not spawner(name):
|
|
failed.append(name)
|
|
|
|
print("Summary:")
|
|
for name in failed:
|
|
print("%s failed" % name)
|
|
else:
|
|
print(USAGE)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main(argv=sys.argv[1:])
|