Peter Zion
2011-May-31 23:36 UTC
[LLVMdev] Assertion failure in MC emitter running LLVM libs on Android using android-ndk
Hello,
I am encountering a strange assertion failure using the LLVM libraries
cross-compiled for Android using the Android NDK. I am using the official
release of LLVM-2.9.
The IR which is causing the assertion failure is the following:
define void @__construct_Byte__Integer(i8* nocapture %byteLValue, i32
%integerRValue) inlinehint {
entry:
%0 = trunc i32 %integerRValue to i8
store i8 %0, i8* %byteLValue
ret void
}
define void @entry() inlinehint {
entry:
%castToByte = alloca i8
call void @__construct_Byte__Integer(i8* %castToByte, i32 16)
%0 = load i8* %castToByte
ret void
}
And the assertion failure is the following:
assertion "isReg() && "This is not a register
operand!"" failed: file
"/Users/pzion/Fabric/ThirdParty/Build/Android/arm/llvm-2.9/include/llvm/CodeGen/MachineOperand.h",
line 202, function "unsigned int llvm::MachineOperand::getReg() const"
Stack dump:
0. Running pass 'ARM Machine Code Emitter' on function
'@__construct_Byte__Integer'
The library is running on the Android device which has a cortex-9 CPU. The
library usage to generate the machine code is:
std::string errStr;
llvm::EngineBuilder builder( module.get() );
builder.setErrorStr( &errStr );
builder.setEngineKind( llvm::EngineKind::JIT );
std::auto_ptr<llvm::ExecutionEngine> executionEngine(
builder.create() );
llvm::Function *llvmEntry = module->getFunction( "entry" );
void (*entryPtr)() = (void
(*)())executionEngine->getPointerToFunction( llvmEntry );
What is so strange about this error is that if I instead output the ARM assembly
language then assembly it on the build host using the Android NDK toolchain, it
assembles without any problem at all. The library usage to generate the
assembly is:
std::string errorStr;
std::string targetTriple = llvm::sys::getHostTriple();
const llvm::Target *target = llvm::TargetRegistry::lookupTarget(
targetTriple, errorStr );
llvm::TargetMachine *targetMachine = target->createTargetMachine(
targetTriple, "" );
targetMachine->setAsmVerbosityDefault( true );
llvm::FunctionPassManager *functionPassManager = new
llvm::FunctionPassManager( module.get() );
targetMachine->addPassesToEmitFile(
*functionPassManager, llvm::fouts(),
llvm::TargetMachine::CGFT_AssemblyFile, optLevel );
functionPassManager->doInitialization();
llvm::Module::FunctionListType &functionList =
module->getFunctionList();
for ( llvm::Module::FunctionListType::iterator it=functionList.begin();
it!=functionList.end(); ++it )
functionPassManager->run( *it );
delete functionPassManager;
It seems very bizarre to me that the back end can generate the assembly code but
can't generate the machine code directly.
Note that I have been unable to get the command-line tools (eg. llc) to
cross-compile to Android, but I don't actually need them for my project; I
use the LLVM libraries directly. Note also that I'm explicitly replacing
the cross-compiled tblgen with one compiled (from the same version of LLVM) for
the build machine (x86_64-darwin-10) in order to make the compile work; but from
what I understand the tblgen output is platform independent anyway.
Can anyone offer me any clues as to what might be going wrong here? Explicitly
specifying -march=arm and/or -mcpu=cortex-9 to the EngineBuilder makes no
difference.
Thanks in advance,
Peter Zion
Reasonably Related Threads
- [LLVMdev] how to build eglibc using llvm-gcc without unsupported -fno-toplevel-reorder
- [LLVMdev] how to build eglibc using llvm-gcc without unsupported -fno-toplevel-reorder
- [LLVMdev] AsmPrinter question
- [LLVMdev] LLVM2.2 x64 JIT trouble on VStudio build
- [LLVMdev] LLVM2.2 x64 JIT trouble on VStudio build
