Beispiel #1
0
def test_linker():
    context = llvm.getGlobalContext()

    mA = llvm.Module.new("modA", context)
    mB = llvm.Module.new("modB", context)

    def create_function(m, name):
        int32ty = llvm.Type.getIntNTy(context, 32)
        fnty = llvm.FunctionType.get(int32ty, [int32ty], False)
        fn = m.getOrInsertFunction(name, fnty)._downcast(llvm.Function)
        bb = llvm.BasicBlock.Create(context, "entry", fn, None)
        builder = llvm.IRBuilder.new(context)
        builder.SetInsertPoint(bb)
        builder.CreateRet(fn.getArgumentList()[0])

    create_function(mA, 'foo')
    create_function(mB, 'bar')

    errmsg = StringIO()
    linkermode = llvm.Linker.LinkerMode.PreserveSource
    failed = llvm.Linker.LinkModules(mA, mB, linkermode, errmsg)
    assert not failed, errmsg.getvalue()
    assert mA.getFunction('foo')
    assert mA.getFunction('bar')

    assert set(mA.list_functions()) == set(
        [mA.getFunction('foo'), mA.getFunction('bar')])
Beispiel #2
0
def test_linker():
    context = llvm.getGlobalContext()

    mA = llvm.Module.new("modA", context)
    mB = llvm.Module.new("modB", context)

    def create_function(m, name):
        int32ty = llvm.Type.getIntNTy(context, 32)
        fnty = llvm.FunctionType.get(int32ty, [int32ty], False)
        fn = m.getOrInsertFunction(name, fnty)._downcast(llvm.Function)
        bb = llvm.BasicBlock.Create(context, "entry", fn, None)
        builder = llvm.IRBuilder.new(context)
        builder.SetInsertPoint(bb)
        builder.CreateRet(fn.getArgumentList()[0])

    create_function(mA, 'foo')
    create_function(mB, 'bar')

    errmsg = StringIO()
    linkermode = llvm.Linker.LinkerMode.PreserveSource
    failed = llvm.Linker.LinkModules(mA, mB, linkermode, errmsg)
    assert not failed, errmsg.getvalue()
    assert mA.getFunction('foo')
    assert mA.getFunction('bar')

    assert set(mA.list_functions()) == set([mA.getFunction('foo'),
                                            mA.getFunction('bar')])
Beispiel #3
0
def test_intrinsic():
    context = llvm.getGlobalContext()
    m = llvm.Module.new("modname", context)
    INTR_SIN = 1652
    floatty = llvm.Type.getFloatTy(context)
    fn = llvm.Intrinsic.getDeclaration(m, INTR_SIN, [floatty])
    assert 'llvm.sin.f32' in str(fn)
    fn.eraseFromParent()
    assert 'llvm.sin.f32' not in str(m)
Beispiel #4
0
def test_intrinsic():
    context = llvm.getGlobalContext()
    m = llvm.Module.new("modname", context)
    INTR_SIN = 1652
    floatty = llvm.Type.getFloatTy(context)
    fn = llvm.Intrinsic.getDeclaration(m, INTR_SIN, [floatty])
    assert 'llvm.sin.f32' in str(fn)
    fn.eraseFromParent()
    assert 'llvm.sin.f32' not in str(m)
Beispiel #5
0
def test_sequentialtypes():
    context = llvm.getGlobalContext()
    int32ty = llvm.Type.getInt32Ty(context)
    ary_int32x4 = llvm.ArrayType.get(int32ty, 4)
    assert '[4 x i32]' == str(ary_int32x4)
    ptr_int32 = llvm.PointerType.get(int32ty, 1)
    assert 'i32 addrspace(1)*' == str(ptr_int32)
    vec_int32x4 = llvm.VectorType.get(int32ty, 4)
    assert '<4 x i32>' == str(vec_int32x4)
Beispiel #6
0
def test_sequentialtypes():
    context = llvm.getGlobalContext()
    int32ty = llvm.Type.getInt32Ty(context)
    ary_int32x4 = llvm.ArrayType.get(int32ty, 4)
    assert '[4 x i32]' == str(ary_int32x4)
    ptr_int32 = llvm.PointerType.get(int32ty, 1)
    assert 'i32 addrspace(1)*' == str(ptr_int32)
    vec_int32x4 = llvm.VectorType.get(int32ty, 4)
    assert '<4 x i32>' == str(vec_int32x4)
Beispiel #7
0
def test_constants():
    context = llvm.getGlobalContext()
    int32ty = llvm.Type.getInt32Ty(context)
    ary_int32x4 = llvm.ArrayType.get(int32ty, 4)
    intconst = llvm.ConstantInt.get(int32ty, 123)
    aryconst = llvm.ConstantArray.get(ary_int32x4, [intconst] * 4)
    assert str(aryconst.getAggregateElement(0)) == str(intconst)

    bignum = 4415104608
    int64ty = llvm.Type.getInt64Ty(context)
    const_bignum = llvm.ConstantInt.get(int64ty, 4415104608)
    assert str(bignum) in str(const_bignum)
Beispiel #8
0
def test_constants():
    context = llvm.getGlobalContext()
    int32ty = llvm.Type.getInt32Ty(context)
    ary_int32x4 = llvm.ArrayType.get(int32ty, 4)
    intconst = llvm.ConstantInt.get(int32ty, 123)
    aryconst = llvm.ConstantArray.get(ary_int32x4, [intconst] * 4)
    assert str(aryconst.getAggregateElement(0)) == str(intconst)

    bignum = 4415104608
    int64ty = llvm.Type.getInt64Ty(context)
    const_bignum = llvm.ConstantInt.get(int64ty, 4415104608)
    assert str(bignum) in str(const_bignum)
Beispiel #9
0
def test_globalvariable():
    context = llvm.getGlobalContext()
    m = llvm.Module.new("modname", context)

    ty = llvm.Type.getInt32Ty(context)
    LinkageTypes = llvm.GlobalVariable.LinkageTypes
    linkage = LinkageTypes.ExternalLinkage
    gvar = llvm.GlobalVariable.new(m, ty, False, linkage, None, "apple")
    assert '@apple = external global i32' in str(m)

    gvar2 = m.getNamedGlobal('apple')
    assert gvar2 is gvar

    print(m.list_globals())
Beispiel #10
0
def test_globalvariable():
    context = llvm.getGlobalContext()
    m = llvm.Module.new("modname", context)

    ty = llvm.Type.getInt32Ty(context)
    LinkageTypes = llvm.GlobalVariable.LinkageTypes
    linkage = LinkageTypes.ExternalLinkage
    gvar = llvm.GlobalVariable.new(m, ty, False, linkage, None, "apple")
    assert '@apple = external global i32' in str(m)

    gvar2 = m.getNamedGlobal('apple')
    assert gvar2 is gvar

    print(m.list_globals())
Beispiel #11
0
def test_structtype():
    context = llvm.getGlobalContext()
    m = llvm.Module.new("modname", context)

    assert m.getTypeByName("truck") is None

    truck = llvm.StructType.create(context, "truck")
    assert 'type opaque' in str(truck)
    elemtys = [llvm.Type.getInt32Ty(context), llvm.Type.getDoubleTy(context)]
    truck.setBody(elemtys)

    assert 'i32' in str(truck)
    assert 'double' in str(truck)

    assert m.getTypeByName("truck") is truck
Beispiel #12
0
def test_structtype():
    context = llvm.getGlobalContext()
    m = llvm.Module.new("modname", context)

    assert m.getTypeByName("truck") is None

    truck = llvm.StructType.create(context, "truck")
    assert 'type opaque' in str(truck)
    elemtys = [llvm.Type.getInt32Ty(context), llvm.Type.getDoubleTy(context)]
    truck.setBody(elemtys)

    assert 'i32' in str(truck)
    assert 'double' in str(truck)

    assert m.getTypeByName("truck") is truck
Beispiel #13
0
# -*- coding: utf-8 -*-
"""
Support for math as a postpass on LLVM IR.
"""

from __future__ import print_function, division, absolute_import

from . import libs
from . import ltypes
from . import complex_support

import llvm.core as lc
from llvmpy.api import llvm

llvm_context = llvm.getGlobalContext()

#===------------------------------------------------------------------===
# Complex linking
#===------------------------------------------------------------------===


def _link_complex(engine, module, library, lfunc_src, lfunc_dst):
    """
    Rewrite
        %r = sin({ double, double}* a)
    to
        %a1 = bitcast { double, double}* a to %struct.npy_cdouble*
        %r = sin(%struct.npy_cdouble* a)
    """
    module, lsrc, ldst = module._ptr, lfunc_src._ptr, lfunc_dst._ptr
    argtypes = [arg.getType() for arg in ldst.getArgumentList()]
Beispiel #14
0
def test_basic_jit_use():
    context = llvm.getGlobalContext()

    m = llvm.Module.new("modname", context)
    print(m.getModuleIdentifier())
    m.setModuleIdentifier('modname2')
    print(m.getModuleIdentifier())
    print('endianness', m.getEndianness())
    assert m.getEndianness() == llvm.Module.Endianness.AnyEndianness
    print('pointer-size', m.getPointerSize())
    assert m.getPointerSize() == llvm.Module.PointerSize.AnyPointerSize
    m.dump()

    os = extra.make_raw_ostream_for_printing()
    m.print_(os, None)
    print(os.str())

    int1ty = llvm.Type.getInt1Ty(context)
    int1ty.dump()

    assert int1ty.isIntegerTy(1)

    fnty = llvm.FunctionType.get(int1ty, False)
    fnty.dump()

    types = [llvm.Type.getIntNTy(context, 8), llvm.Type.getIntNTy(context, 32)]
    fnty = llvm.FunctionType.get(llvm.Type.getIntNTy(context, 8), types, False)

    print(fnty)

    const = m.getOrInsertFunction("foo", fnty)
    fn = const._downcast(llvm.Function)
    print(fn)
    assert fn.hasName()
    assert 'foo' == fn.getName()
    fn.setName('bar')
    assert 'bar' == fn.getName()

    assert fn.getReturnType().isIntegerTy(8)

    assert fnty is fn.getFunctionType()

    assert fn.isVarArg() == False
    assert fn.getIntrinsicID() == 0
    assert not fn.isIntrinsic()

    fn_uselist = fn.list_use()
    assert isinstance(fn_uselist, list)
    assert len(fn_uselist) == 0

    builder = llvm.IRBuilder.new(context)
    print(builder)

    bb = llvm.BasicBlock.Create(context, "entry", fn, None)
    assert bb.empty()
    builder.SetInsertPoint(bb)

    assert bb.getTerminator() is None

    arg0, arg1 = fn.getArgumentList()
    print(arg0, arg1)

    extended = builder.CreateZExt(arg0, arg1.getType())
    result = builder.CreateAdd(extended, arg1)
    ret = builder.CreateTrunc(result, fn.getReturnType())
    builder.CreateRet(ret)

    print(arg0.list_use())

    print(fn)

    errio = StringIO()
    print(m)

    # verifier
    action = llvm.VerifierFailureAction.ReturnStatusAction

    corrupted = llvm.verifyFunction(fn, action)
    assert not corrupted
    corrupted = llvm.verifyModule(m, action, errio)
    print(corrupted)
    assert not corrupted, errio.getvalue()

    # build pass manager
    pmb = llvm.PassManagerBuilder.new()
    pmb.OptLevel = 3
    assert pmb.OptLevel == 3
    pmb.LibraryInfo = llvm.TargetLibraryInfo.new()
    pmb.Inliner = llvm.createFunctionInliningPass()

    fpm = llvm.FunctionPassManager.new(m)
    pm = llvm.PassManager.new()

    pmb.populateFunctionPassManager(fpm)
    pmb.populateModulePassManager(pm)

    fpm.doInitialization()
    fpm.run(fn)
    fpm.doFinalization()

    pm.run(m)

    print(m)

    # build engine

    ee = llvm.ExecutionEngine.createJIT(m, errio)
    print(ee, errio.getvalue())
    print(ee.getDataLayout().getStringRepresentation())

    datalayout_str = 'e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64'

    assert datalayout_str == str(llvm.DataLayout.new(datalayout_str))
    assert datalayout_str == str(
        llvm.DataLayout.new(str(llvm.DataLayout.new(datalayout_str))))

    fn2 = ee.FindFunctionNamed(fn.getName())
    assert fn2 is fn

    assert ee.getPointerToFunction(fn)
    assert ee.getPointerToNamedFunction('printf')

    gv0 = llvm.GenericValue.CreateInt(arg0.getType(), 12, False)
    gv1 = llvm.GenericValue.CreateInt(arg1.getType(), -32, True)

    assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth()
    assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth()

    assert gv0.toUnsignedInt() == 12
    assert gv1.toSignedInt() == -32

    gv1 = llvm.GenericValue.CreateInt(arg1.getType(), 32, False)

    gvR = ee.runFunction(fn, (gv0, gv1))

    assert 44 == gvR.toUnsignedInt()

    # write bitcode
    bc_buffer = BytesIO()
    llvm.WriteBitcodeToFile(m, bc_buffer)
    bc = bc_buffer.getvalue()
    bc_buffer.close()

    # read bitcode
    errbuf = BytesIO()
    m2 = llvm.ParseBitCodeFile(bc, context, errbuf)
    if not m2:
        raise Exception(errbuf.getvalue())
    else:
        m2.setModuleIdentifier(m.getModuleIdentifier())
        assert str(m2) == str(m)

    # parse llvm ir
    m3 = llvm.ParseAssemblyString(str(m), None, llvm.SMDiagnostic.new(),
                                  context)
    m3.setModuleIdentifier(m.getModuleIdentifier())
    assert str(m3) == str(m)

    # test clone
    m4 = llvm.CloneModule(m)
    assert m4 is not m
    assert str(m4) == str(m)
Beispiel #15
0
def test_engine_builder():
    llvm.InitializeNativeTarget()
    context = llvm.getGlobalContext()

    m = llvm.Module.new("modname", context)

    int32ty = llvm.Type.getIntNTy(context, 32)
    fnty = llvm.FunctionType.get(int32ty, [int32ty], False)
    fn = m.getOrInsertFunction("foo", fnty)._downcast(llvm.Function)
    bb = llvm.BasicBlock.Create(context, "entry", fn, None)
    builder = llvm.IRBuilder.new(context)
    builder.SetInsertPoint(bb)
    builder.CreateRet(fn.getArgumentList()[0])

    print(fn)

    eb = llvm.EngineBuilder.new(m)
    eb2 = eb.setEngineKind(llvm.EngineKind.Kind.JIT)
    assert eb is eb2
    eb.setOptLevel(llvm.CodeGenOpt.Level.Aggressive).setUseMCJIT(False)

    tm = eb.selectTarget()

    print('target triple:', tm.getTargetTriple())
    print('target cpu:', tm.getTargetCPU())
    print('target feature string:', tm.getTargetFeatureString())

    target = tm.getTarget()
    print('target name:', target.getName())
    print('target short description:', target.getShortDescription())

    assert target.hasJIT()
    assert target.hasTargetMachine()

    ee = eb.create(tm)

    triple = llvm.Triple.new('x86_64-unknown-linux')
    assert triple.getArchName() == 'x86_64'
    assert triple.getVendorName() == 'unknown'
    assert triple.getOSName() == 'linux'
    assert triple.isArch64Bit()
    assert not triple.isArch32Bit()
    triple_32variant = triple.get32BitArchVariant()
    assert triple_32variant.isArch32Bit()

    print(tm.getDataLayout())

    pm = llvm.PassManager.new()
    pm.add(llvm.DataLayout.new(str(tm.getDataLayout())))
    pm.add(llvm.TargetLibraryInfo.new())

    # write assembly
    pm = llvm.PassManager.new()
    pm.add(llvm.DataLayout.new(str(tm.getDataLayout())))

    raw = extra.make_raw_ostream_for_printing()
    formatted = llvm.formatted_raw_ostream.new(raw, False)

    cgft = llvm.TargetMachine.CodeGenFileType.CGFT_AssemblyFile
    failed = tm.addPassesToEmitFile(pm, formatted, cgft, False)
    assert not failed

    pm.run(m)

    formatted.flush()
    raw.flush()
    asm = raw.str()
    print(asm)
    assert 'foo' in asm
Beispiel #16
0
def test_basic_jit_use():
    context = llvm.getGlobalContext()

    m = llvm.Module.new("modname", context)
    print(m.getModuleIdentifier())
    m.setModuleIdentifier('modname2')
    print(m.getModuleIdentifier())
    print('endianness', m.getEndianness())
    assert m.getEndianness() == llvm.Module.Endianness.AnyEndianness
    print('pointer-size', m.getPointerSize())
    assert m.getPointerSize() == llvm.Module.PointerSize.AnyPointerSize
    m.dump()


    os = extra.make_raw_ostream_for_printing()
    m.print_(os, None)
    print(os.str())


    int1ty = llvm.Type.getInt1Ty(context)
    int1ty.dump()

    assert int1ty.isIntegerTy(1)

    fnty = llvm.FunctionType.get(int1ty, False)
    fnty.dump()

    types = [llvm.Type.getIntNTy(context, 8), llvm.Type.getIntNTy(context, 32)]
    fnty = llvm.FunctionType.get(llvm.Type.getIntNTy(context, 8), types, False)

    print(fnty)

    const = m.getOrInsertFunction("foo", fnty)
    fn = const._downcast(llvm.Function)
    print(fn)
    assert fn.hasName()
    assert 'foo' == fn.getName()
    fn.setName('bar')
    assert 'bar' == fn.getName()

    assert fn.getReturnType().isIntegerTy(8)

    assert fnty is fn.getFunctionType()

    assert fn.isVarArg() == False
    assert fn.getIntrinsicID() == 0
    assert not fn.isIntrinsic()

    fn_uselist = fn.list_use()
    assert isinstance(fn_uselist, list)
    assert len(fn_uselist) == 0

    builder = llvm.IRBuilder.new(context)
    print(builder)

    bb = llvm.BasicBlock.Create(context, "entry", fn, None)
    assert bb.empty()
    builder.SetInsertPoint(bb)

    assert bb.getTerminator() is None

    arg0, arg1 = fn.getArgumentList()
    print(arg0, arg1)

    extended = builder.CreateZExt(arg0, arg1.getType())
    result = builder.CreateAdd(extended, arg1)
    ret = builder.CreateTrunc(result, fn.getReturnType())
    builder.CreateRet(ret)

    print(arg0.list_use())

    print(fn)

    errio = StringIO()
    print(m)

    # verifier
    action = llvm.VerifierFailureAction.ReturnStatusAction

    corrupted = llvm.verifyFunction(fn, action)
    assert not corrupted
    corrupted = llvm.verifyModule(m, action, errio)
    print(corrupted)
    assert not corrupted, errio.getvalue()

    # build pass manager
    pmb = llvm.PassManagerBuilder.new()
    pmb.OptLevel = 3
    assert pmb.OptLevel == 3
    pmb.LibraryInfo = llvm.TargetLibraryInfo.new()
    pmb.Inliner = llvm.createFunctionInliningPass()

    fpm = llvm.FunctionPassManager.new(m)
    pm = llvm.PassManager.new()

    pmb.populateFunctionPassManager(fpm)
    pmb.populateModulePassManager(pm)

    fpm.doInitialization()
    fpm.run(fn)
    fpm.doFinalization()

    pm.run(m)

    print(m)

    # build engine

    ee = llvm.ExecutionEngine.createJIT(m, errio)
    print(ee, errio.getvalue())
    print(ee.getDataLayout().getStringRepresentation())

    datalayout_str = 'e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64'

    assert datalayout_str == str(llvm.DataLayout.new(datalayout_str))
    assert datalayout_str == str(llvm.DataLayout.new(str(llvm.DataLayout.new(datalayout_str))))

    fn2 = ee.FindFunctionNamed(fn.getName())
    assert fn2 is fn

    assert ee.getPointerToFunction(fn)
    assert ee.getPointerToNamedFunction('printf')

    gv0 = llvm.GenericValue.CreateInt(arg0.getType(), 12, False)
    gv1 = llvm.GenericValue.CreateInt(arg1.getType(), -32, True)

    assert gv0.valueIntWidth() == arg0.getType().getIntegerBitWidth()
    assert gv1.valueIntWidth() == arg1.getType().getIntegerBitWidth()

    assert gv0.toUnsignedInt() == 12
    assert gv1.toSignedInt() == -32

    gv1 = llvm.GenericValue.CreateInt(arg1.getType(), 32, False)

    gvR = ee.runFunction(fn, (gv0, gv1))

    assert 44 == gvR.toUnsignedInt()

    # write bitcode
    bc_buffer = BytesIO()
    llvm.WriteBitcodeToFile(m, bc_buffer)
    bc = bc_buffer.getvalue()
    bc_buffer.close()

    # read bitcode
    errbuf = BytesIO()
    m2 = llvm.ParseBitCodeFile(bc, context, errbuf)
    if not m2:
        raise Exception(errbuf.getvalue())
    else:
        m2.setModuleIdentifier(m.getModuleIdentifier())
        assert str(m2) == str(m)

    # parse llvm ir
    m3 = llvm.ParseAssemblyString(str(m), None, llvm.SMDiagnostic.new(), context)
    m3.setModuleIdentifier(m.getModuleIdentifier())
    assert str(m3) == str(m)

    # test clone
    m4 = llvm.CloneModule(m)
    assert m4 is not m
    assert str(m4) == str(m)
Beispiel #17
0
from io import BytesIO
from llvmpy.api import llvm

llvm_context = llvm.getGlobalContext()

def verify_module(module):
    action = llvm.VerifierFailureAction.ReturnStatusAction
    errio = BytesIO()
    broken = llvm.verifyModule(module, action, errio)
    if broken:
        raise Exception(errio.getvalue())

def verify_function(func):
    actions = llvm.VerifierFailureAction
    broken = llvm.verifyFunction(func,
                                     actions.ReturnStatusAction)
    if broken:
        # If broken, then re-run to print the message
        llvm.verifyFunction(func, actions.PrintMessageAction)
        raise Exception("Funciton verification failed for %s" % func.getName())


def get_or_insert_func(lmod, name, retty, args, vararg=False):
    "args --- can be values or types"
    if args and not isinstance(args[0], llvm.Type):
        argtys = [arg.getType() for arg in args]
    else:
        argtys = args
    fnty = llvm.FunctionType.get(retty, argtys, vararg)
    fn = lmod.getOrInsertFunction(name, fnty)
    return fn._downcast(llvm.Function)
Beispiel #18
0
def test_engine_builder():
    llvm.InitializeNativeTarget()
    context = llvm.getGlobalContext()

    m = llvm.Module.new("modname", context)

    int32ty = llvm.Type.getIntNTy(context, 32)
    fnty = llvm.FunctionType.get(int32ty, [int32ty], False)
    fn = m.getOrInsertFunction("foo", fnty)._downcast(llvm.Function)
    bb = llvm.BasicBlock.Create(context, "entry", fn, None)
    builder = llvm.IRBuilder.new(context)
    builder.SetInsertPoint(bb)
    builder.CreateRet(fn.getArgumentList()[0])

    print(fn)

    eb = llvm.EngineBuilder.new(m)
    eb2 = eb.setEngineKind(llvm.EngineKind.Kind.JIT)
    assert eb is eb2
    eb.setOptLevel(llvm.CodeGenOpt.Level.Aggressive).setUseMCJIT(False)

    tm = eb.selectTarget()

    print('target triple:', tm.getTargetTriple())
    print('target cpu:', tm.getTargetCPU())
    print('target feature string:', tm.getTargetFeatureString())

    target = tm.getTarget()
    print('target name:', target.getName())
    print('target short description:', target.getShortDescription())

    assert target.hasJIT()
    assert target.hasTargetMachine()

    ee = eb.create(tm)

    triple = llvm.Triple.new('x86_64-unknown-linux')
    assert triple.getArchName() == 'x86_64'
    assert triple.getVendorName() == 'unknown'
    assert triple.getOSName() == 'linux'
    assert triple.isArch64Bit()
    assert not triple.isArch32Bit()
    triple_32variant = triple.get32BitArchVariant()
    assert triple_32variant.isArch32Bit()

    print(tm.getDataLayout())

    pm = llvm.PassManager.new()
    pm.add(llvm.DataLayout.new(str(tm.getDataLayout())))
    pm.add(llvm.TargetLibraryInfo.new())

    # write assembly
    pm = llvm.PassManager.new()
    pm.add(llvm.DataLayout.new(str(tm.getDataLayout())))

    raw = extra.make_raw_ostream_for_printing()
    formatted = llvm.formatted_raw_ostream.new(raw, False)

    cgft = llvm.TargetMachine.CodeGenFileType.CGFT_AssemblyFile
    failed = tm.addPassesToEmitFile(pm, formatted, cgft, False)
    assert not failed

    pm.run(m)

    formatted.flush()
    raw.flush()
    asm = raw.str()
    print(asm)
    assert 'foo' in asm