Interpreter::Interpreter(Module *M) : ExecutionEngine(M), TD(M) { memset(&ExitValue, 0, sizeof(ExitValue)); <----- ... } The problem with this line is that it leaves the APInt value within ExitValue in a broken state (bit width cannot be zero). If you run a function with no return value through the interpreter it will crash as the ExitValue is passed out of the interpreter's run function as it gets to the APInt copy constructor. This problem is easily reproducable with by running a void function through the interpeter. I've seen this repro both on Mac OSX and Vista.
Hi Chuck, Thanks for the report. The code you highlighed does look to be in error and I have a patch for it, but I can't reproduce the original problem. I've got a test case like this: ; PR1486 ; RUN: llvm-as %s -f -o %t.bc ; RUN: lli -force-interpreter=true %t.bc ; Test that void function results don't cause an assert define void @doNothing() { ret void } define i32 @main() { call void @doNothing() ret i32 0 } I'm trying this on Linux, but I doubt platform makes a difference for this problem. Is this the kind of test case you were using?
Comments from Chuck, via email: Here'e the function that's running, though I have seen it with something like your doNothing function alone. The thing we don't have is the main function. define void @evaluateDependents(float* %colorValue) { FnTemporariesBlock: br label %FunctionBlock FunctionBlock: ; preds = %FnTemporariesBlock call float @fabsf( float -5.000000e-001 ) ; <float>:0 [#us es=1] store float %0, float* %colorValue br label %DestructorBlock DestructorBlock: ; preds = %FunctionBlock ret void } declare float @fabsf(float) Here's how we call in: llvm::Function* pExecutableFunction = pEE->FindFunctionNamed("evaluateDependents"); llvm::GenericValue GV = pEE->runFunction( pExecutableFunction, parameters );
Chuck, I can't easily reproduce that (limited time here), but perhaps you could try this patch: Index: Interpreter.cpp =================================================================== RCS file: /var/cvs/llvm/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp,v retrieving revision 1.39 diff -t -d -u -p -5 -r1.39 Interpreter.cpp --- Interpreter.cpp 6 Mar 2007 03:05:57 -0000 1.39 +++ Interpreter.cpp 1 Jun 2007 20:08:49 -0000 @@ -52,11 +52,11 @@ ExecutionEngine *Interpreter::create(Mod //===----------------------------------------------------------------------===// // Interpreter ctor - Initialize stuff // Interpreter::Interpreter(Module *M) : ExecutionEngine(M), TD(M) { - memset(&ExitValue, 0, sizeof(ExitValue)); + memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped)); setTargetData(&TD); // Initialize the "backend" initializeExecutionEngine(); initializeExternalFunctions(); emitGlobals(); Instead of memset'ing the whole thing, it just does the "union" part. That should avoid setting 0 bit width in the APInt portion and relieve the problem. If this works for you, please let me know and I'll commit it and close this PR. Thanks, Reid.
If your fix is applied to the intreter constructor and also to the void return path in popStackAndReturnToCaller function in execution.cpp, it works on my system. Thank you for the quick turnaround.
Fix patches here: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070528/050155.html