Open llvmbot opened 8 years ago
Can you please provide a testcase to reproduce the issue? Thanks
After some gdb trace, I found that the bug is caused by the MapValue function. In the source module the only global value used in function is @block_literal_global, and when the inst used @block_literal_global was used from linkFunctionBody to RemapInstruction and then to MapValue, it will first be materializeDeclFor into the Dst module. Then the linkGlobalValueBody and linkGlobalInit will map those global value used in @block_literal_global one by one. So after link we can see @block_literal_global at first, followed by @_NSConcreteGlobalBlock ,@block_descriptor_tmp and the @.str used in @block_descriptor_tmp.
But this order is not correct in a module, the value @__block_literal_global depends on some value declared after it. And when we want to delete the module there will be assert about delete some value that are still have users.
Extended Description
We are using a module as library and link the source code in the library and when the source code has some blocks there are some bugs with the global value. In debug version the ~Module will assert.
Here is llvm ir for global values before link and after link: Before link: @_NSConcreteGlobalBlock = external global i8 @.str = private unnamed_addr addrspace(2) constant [9 x i8] c"i12@?0i8\00", align 1 @__block_descriptor_tmp = internal constant { i64, i64, i8 addrspace(2), i8 addrspace(2) } { i64 0, i64 32, i8 addrspace(2) getelementptr inbounds ([9 x i8], [9 x i8] addrspace(2) @.str, i32 0, i32 0), i8 addrspace(2) null }
@block_literal_global = internal constant { i8*, i32, i32, i8, %struct.block_descriptor* } { i8* @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8 bitcast (i32 (i8, i32) @test_block_invoke to i8*), %struct.block_descriptor bitcast ({ i64, i64, i8 addrspace(2), i8 addrspace(2) } @block_descriptor_tmp to %struct.block_descriptor*) }, align 8
After link: @block_literal_global = internal constant { i8*, i32, i32, i8, %struct.block_descriptor* } { i8* @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8 bitcast (i32 (i8, i32) @test_block_invoke to i8*), %struct.block_descriptor bitcast ({ i64, i64, i8 addrspace(2), i8 addrspace(2) } @block_descriptor_tmp to %struct.block_descriptor) }, align 8 @_NSConcreteGlobalBlock = external global i8 @__block_descriptor_tmp = internal constant { i64, i64, i8 addrspace(2), i8 addrspace(2) } { i64 0, i64 32, i8 addrspace(2) getelementptr inbounds ([9 x i8], [9 x i8] addrspace(2) @.str, i32 0, i32 0), i8 addrspace(2)* null } @.str = private unnamed_addr addrspace(2) constant [9 x i8] c"i12@?0i8\00", align 1
As the global valve orders change, the dependency of these global values are messed.
It seems the bug was caused by ModuleLinker::linkIfNeeded with a recursion call but with a wrong order.