[LLVMdev] Fwd: error while linking modules with exception handling demo code

Duncan Sands baldrick at free.fr
Sun Dec 16 07:21:20 PST 2012


Hi Charles, can you reduce to two .ll files that cause llvm-link to assert?

Ciao, Duncan.

On 13/12/12 17:57, charles quarra wrote:
> ---------- Forwarded message ----------
> From: charles quarra <charllsnotieneningunputocorreo at gmail.com>
> Date: 2012/12/13
> Subject: error while linking modules with exception handling demo code
> To: llvmdev at cs.uiuc.edu
>
>
> Hi,
>
>
> I am building a module X with an arithmetic function foo, a module Y
> with an arithmetic function foo2 that invokes foo. For the invocation
> be a proper one (being able to handle exceptions correctly) i
> incorporated a third module that has defined exception-handling code
> that i've taken from the ExceptionDemo sample. First i'll post the
> module dump, the failed assertion and then i'll explain a bit about
> how do i generate the code:
>
> this is the module ExecutableCodeModule dump, which is the module that
> is used by the ExecutionEngine (not using new MCJIT, but it is not
> relevant for this question, since the error happens during linkage).
> It contains definitions from the ExceptionDemo sample AND the foo
> function of module X already linked
>
> (modules are being linked with
> linker()->LinkModules(ExecutableCodeModule , moduleToLink,
> llvm::Linker::PreserveSource, &errorMsg);
>
> Exception Demo is from
> https://llvm.org/svn/llvm-project/llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp
>
> ; ModuleID = 'ExecutableCodeModule'
>
> @typeInfo0 = constant { i32 } zeroinitializer
> @typeInfo1 = constant { i32 } { i32 1 }
> @typeInfo2 = constant { i32 } { i32 2 }
> @typeInfo3 = constant { i32 } { i32 3 }
> @typeInfo4 = constant { i32 } { i32 4 }
> @typeInfo5 = constant { i32 } { i32 5 }
> @typeInfo6 = constant { i32 } { i32 6 }
>
> declare void @print32Int(i32, i8*)
>
> declare void @print64Int(i64, i8*)
>
> declare void @printStr(i8*)
>
> declare void @throwCppException(i32)
>
> declare void @deleteOurException(i8*)
>
> declare i8* @createOurException(i32)
>
> declare i32 @_Unwind_RaiseException(i8*) noreturn
>
> declare i32 @_Unwind_Resume(i8*) noreturn
>
> declare i32 @ourPersonality(i32, i32, i64, i8*, i8*)
>
> declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone
>
> define i32 @foo(i32) {
>    %g = alloca i32
>    %bar = alloca i32
>    store i32 %0, i32* %bar
>    %"argument read" = load i32* %bar
>    %addtmp = add i32 %"argument read", 2
>    store i32 %addtmp, i32* %g
>    %"argument read1" = load i32* %bar
>    %read = load i32* %g
>    %"Code::Op::Mul" = mul i32 %"argument read1", %read
>    ret i32 %"Code::Op::Mul"
> }
>
> this is module Y, which is where foo2 is generated. When it is
> supposed to invoke foo, i've placed
> createCatchWrappedInvokeFunction(*module, *excptModule,
>                                                      buildParameters.builder,
>
> *buildParameters.getFunctionPassManager(),
>                                                      *result, //result
> is llvm::Function pointing to foo in module X
>                                                      "invoke foo",
>                                                      numExceptionTypesToCatch,
>                                                      innerExceptionTypesToCatch);
>
> (at the end i put the code for createCatchWrappedInvokeFunction, which
> is slightly modified to allow for things like printStr and
> createOurException that exists in the separate exception handling
> module to be used in the module Y)
>
> ; ModuleID = 'Y'
>
> @0 = linker_private constant [52 x i8] c"Gen: Executing finally block
> finally in invoke foo\0A\00"
> @1 = linker_private constant [52 x i8] c"Gen: Executing catch block
> typeInfo6 in invoke foo\0A\00"
> @2 = linker_private constant [52 x i8] c"Gen: Executing catch block
> typeInfo2 in invoke foo\0A\00"
> @3 = linker_private constant [52 x i8] c"Gen: Executing catch block
> typeInfo4 in invoke foo\0A\00"
> @4 = linker_private constant [43 x i8] c"Gen: In end block: exiting in
> invoke foo.\0A\00"
> @5 = linker_private constant [34 x i8] c"Gen: No exception in invoke foo!\0A\00"
> @6 = linker_private constant [34 x i8] c"Gen: Foreign exception received.\0A\00"
> @7 = linker_private constant [67 x i8] c"Gen: Exception type <%d>
> received (stack unwound)  in invoke foo.\0A\00"
>
> define i32 @foo2(i32) {
>    %h = alloca i32
>    %g = alloca i32
>    %bar = alloca i32
>    store i32 %0, i32* %bar
>    %"argument read" = load i32* %bar
>    %"Code::Op::Mul" = mul i32 %"argument read", 5
>    store i32 %"Code::Op::Mul", i32* %g
>    %read = load i32* %g
> }
>
> define void @"invoke foo"(i32 %exceptTypeToThrow) {
> entry:
>    %caughtResultStorage = alloca { i8*, i32 }
>    store { i8*, i32 } zeroinitializer, { i8*, i32 }* %caughtResultStorage
>    %exceptionStorage = alloca i8*
>    store i8* null, i8** %exceptionStorage
>    %exceptionCaught = alloca i8
>    store i8 0, i8* %exceptionCaught
>    %0 = invoke i32 @foo(i32 %exceptTypeToThrow)
>            to label %normal unwind label %exception
>
> normal:                                           ; preds = %entry
>    call void @printStr(i8* getelementptr inbounds ([34 x i8]* @5, i32 0, i32 0))
>    br label %finally
>
> exception:                                        ; preds = %entry
>    %1 = landingpad { i8*, i32 } personality i32 (i32, i32, i64, i8*,
> i8*)* @ourPersonality
>            cleanup
>            catch { i32 }* @typeInfo6
>            catch { i32 }* @typeInfo2
>            catch { i32 }* @typeInfo4
>    %2 = extractvalue { i8*, i32 } %1, 0
>    %3 = extractvalue { i8*, i32 } %1, 1
>    store { i8*, i32 } %1, { i8*, i32 }* %caughtResultStorage
>    store i8* %2, i8** %exceptionStorage
>    store i8 1, i8* %exceptionCaught
>    %4 = bitcast i8* %2 to { i64 }*
>    %5 = getelementptr inbounds { i64 }* %4, i32 0, i32 0
>    %6 = load i64* %5
>    %7 = icmp eq i64 %6, 8026094035810743040
>    br i1 %7, label %exceptionRoute, label %externalException
>
> exceptionRoute:                                   ; preds = %exception
>    %8 = getelementptr i8* %2, i64 4294967280
>    %9 = bitcast i8* %8 to { { i32 } }*
>    %10 = getelementptr inbounds { { i32 } }* %9, i32 0, i32 0
>    %11 = getelementptr inbounds { i32 }* %10, i32 0, i32 0
>    %12 = load i32* %11
>    call void @print32Int(i32 %12, i8* getelementptr inbounds ([67 x
> i8]* @7, i32 0, i32 0))
>    switch i32 %3, label %finally [
>      i32 1, label %typeInfo6
>      i32 2, label %typeInfo2
>      i32 3, label %typeInfo4
>    ]
>    store i32 %0, i32* %h
>    %"argument read" = load i32* %bar
>    %read = load i32* %h
>    %addtmp = add i32 %"argument read", %read
>    ret i32 %addtmp
>
> externalException:                                ; preds = %exception
>    call void @printStr(i8* getelementptr inbounds ([34 x i8]* @6, i32 0, i32 0))
>    br label %finally
>
> unwindResume:                                     ; preds = %finally
>    %13 = load { i8*, i32 }* %caughtResultStorage
>    resume { i8*, i32 } %13
>
> end:                                              ; preds = %finally, %finally
>    call void @printStr(i8* getelementptr inbounds ([43 x i8]* @4, i32 0, i32 0))
>    %14 = load i8** %exceptionStorage
>    call void @deleteOurException(i8* %14)
>    ret void
>
> finally:                                          ; preds =
> %exceptionRoute, %externalException, %normal, %typeInfo4, %typeInfo2,
> %typeInfo6
>    call void @printStr(i8* getelementptr inbounds ([52 x i8]* @0, i32 0, i32 0))
>    %15 = load i8* %exceptionCaught
>    switch i8 %15, label %end [
>      i8 2, label %end
>      i8 1, label %unwindResume
>    ]
>
> typeInfo6:                                        ; preds = %exceptionRoute
>    call void @printStr(i8* getelementptr inbounds ([52 x i8]* @1, i32 0, i32 0))
>    store i8 2, i8* %exceptionCaught
>    br label %finally
>
> typeInfo2:                                        ; preds = %exceptionRoute
>    call void @printStr(i8* getelementptr inbounds ([52 x i8]* @2, i32 0, i32 0))
>    store i8 2, i8* %exceptionCaught
>    br label %finally
>
> typeInfo4:                                        ; preds = %exceptionRoute
>    call void @printStr(i8* getelementptr inbounds ([52 x i8]* @3, i32 0, i32 0))
>    store i8 2, i8* %exceptionCaught
>    br label %finally
> }
>
> this is the failed assertion i get during the call to Linker::LinkModules
>
>
> While deleting: i32 (i32)* %foo
> Use still stuck around after Def is destroyed:  %0 = invoke i32
> @foo(i32 %exceptTypeToThrow)
>            to label %normal unwind label %exception
> hivecompilerlibtests: Value.cpp:75: virtual llvm::Value::~Value():
> Assertion `use_empty() && "Uses remain when a value is destroyed!"'
> failed.
>
>
> As a separate but probably related detail, the function 'invoke foo'
> is not being inserted in the foo2 IR. The foo2 invoke generation looks
> like this:
>
> llvm::Module* module =
> Compiler::Services::SymbolResolver::getInstance()->resolveOrCreateModule(
> buildParameters.getLLVMContext() ,
> buildParameters.getModuleDefinition() );
>                          HAssertMsg( 0 != module , " null module ");
>                          llvm::Module* excptModule =
> Compiler::Services::SymbolResolver::getInstance()->resolveOrCreateNativeExceptionHandlingModule(
> buildParameters.getLLVMContext() ); //,
> buildParameters.getModuleDefinition() );
>                          HAssertMsg( 0 != excptModule , " null
> exception module ");
>                          HDebugLogLevel("inside BuildIRExpression:, "
> << dynSym.getSymbolName() << " module resolved? " << excptModule, 0);
>                          Exceptions::InvokeFunctionResult invokeResult
> = Exceptions::createCatchWrappedInvokeFunction(*module, *excptModule,
>                                                      buildParameters.builder,
>
> *buildParameters.getFunctionPassManager(),
>                                                      *result,
>
> std::string("invoke ")+ fnDecl->functionName.get(),
>                                                      numExceptionTypesToCatch,
>                                                      innerExceptionTypesToCatch);
>
> the exceptionModule is being generated as:
>
> Compiler::Detail::Exceptions::initialiseExceptionHandlingStaticStuff(ctx);
> llvm::Module* excptModule = new
> llvm::Module("NativeExceptionHandlingModule" ,
> ctx);Compiler::Detail::Exceptions::createStandardUtilityFunctions(6, *
> excptModule);
>
>
> my slightly modified version of ExceptionDemo is appended as an attachment
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>




More information about the llvm-dev mailing list