llvm ir优化"Use still stuck around after Def is destroyed"错误函数删除
llvm ir optimisation "Use still stuck around after Def is destroyed" error function deletion
您好,我最近升级到了 llvm 4.0,现在我从优化器那里得到了最奇怪的错误,这似乎是最良性的代码。我已经确定了似乎给我以下错误的代码,以及 llvm 给我的关于 <badref>
的断言的打印输出,但是在它正在谈论的代码中看不到 <badref>
。这让我认为这可能是编译器错误或生成的代码不正确。
; ModuleID = '__form__module.$static.196'
source_filename = "__form__module.$static.196"
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
%struct.clousure_type = type { void ()*, %struct.closure_vtable*, i8* }
%struct.closure_vtable = type { %struct.type_info*, void (i8*, i8*)*, void (i8*)*, i8 (i8*, i8*)*, i64 (i8*, i8*)* }
%struct.type_info = type { i8*, i8*, i64, i8, i8, i8, i8, %struct.type_info**, %struct.member_info* }
%struct.member_info = type { i8, %struct.type_info* }
@"$static.159$stub_ptr" = external hidden externally_initialized global void (%struct.clousure_type*, %struct.clousure_type*)*
define hidden void @"$static.196"(%struct.clousure_type*, %struct.clousure_type*, %struct.clousure_type*, i8) {
entry:
%4 = icmp eq i8 %3, 0
br i1 %4, label %bb2, label %bb4
bb2: ; preds = %entry
%5 = icmp eq %struct.clousure_type* %0, %2
br i1 %5, label %bb3, label %bb6
bb3: ; preds = %bb4, %bb2
ret void
bb4: ; preds = %entry
%6 = icmp eq %struct.clousure_type* %1, %2
br i1 %6, label %bb3, label %bb6
bb6: ; preds = %bb4, %bb2
tail call void @"$static.159"(%struct.clousure_type* %0, %struct.clousure_type* %1)
ret void
}
; Function Attrs: alwaysinline
define available_externally hidden void @"$static.159"(%struct.clousure_type*, %struct.clousure_type*) #0 {
entry:
%2 = load void (%struct.clousure_type*, %struct.clousure_type*)*, void (%struct.clousure_type*, %struct.clousure_type*)** @"$static.159$stub_ptr", align 8
tail call void %2(%struct.clousure_type* %0, %struct.clousure_type* %1)
ret void
}
attributes #0 = { alwaysinline }
While deleting: void (%struct.clousure_type*, %struct.clousure_type*)* %$static.159
Use still stuck around after Def is destroyed: call void @"$static.159"(%struct.clousure_type* <badref>, %struct.clousure_type* %0)
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Assertion failed!
Program: C:\Users\RICH\workspace\formvm\Debug\formvm.exe
File: C:\llvm-4.0.0.src\lib\IR\Value.cpp, Line 85
Expression: use_empty() && "Uses remain when a value is destroyed!"
代表上述 2 个函数的优化器正在处理的 llvm ir 代码是以下 2 个函数(从 c++ 生成)。
define private void @gen__fun__return_copy85(%struct.clousure_type*, %struct.clousure_type*, %struct.clousure_type*, i8) {
entry:
%4 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %0, %struct.clousure_type** %4, align 8
%5 = load %struct.clousure_type*, %struct.clousure_type** %4, align 8
%6 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %1, %struct.clousure_type** %6, align 8
%7 = load %struct.clousure_type*, %struct.clousure_type** %6, align 8
%8 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %2, %struct.clousure_type** %8, align 8
%9 = load %struct.clousure_type*, %struct.clousure_type** %8, align 8
%10 = alloca i8, align 8
store i8 %3, i8* %10, align 8
%11 = load i8, i8* %10, align 8
%12 = icmp eq i8 %11, 0
br i1 %12, label %bb2, label %bb4
bb2: ; preds = %entry
%13 = icmp eq %struct.clousure_type* %5, %9
br i1 %13, label %bb3, label %bb6
bb3: ; preds = %bb2
ret void
bb4: ; preds = %entry
%14 = icmp eq %struct.clousure_type* %7, %9
br i1 %14, label %bb5, label %bb6
bb5: ; preds = %bb4
ret void
bb6: ; preds = %bb4, %bb2
call void @_ZN13clousure_typeC2ERKS_(%struct.clousure_type* %5, %struct.clousure_type* %7)
ret void
}
define private void @_ZN13clousure_typeC2ERKS_(%struct.clousure_type* %this, %struct.clousure_type* %rhs) {
%1 = alloca %struct.clousure_type*, align 8
%2 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %this, %struct.clousure_type** %1, align 8
store %struct.clousure_type* %rhs, %struct.clousure_type** %2, align 8
%3 = load %struct.clousure_type*, %struct.clousure_type** %1, align 8
%4 = getelementptr %struct.clousure_type, %struct.clousure_type* %3, i32 0, i32 0
store void ()* null, void ()** %4, align 8
%5 = getelementptr %struct.clousure_type, %struct.clousure_type* %3, i32 0, i32 1
store %struct.closure_vtable* null, %struct.closure_vtable** %5, align 8
%6 = getelementptr %struct.clousure_type, %struct.clousure_type* %3, i32 0, i32 2
store i8* null, i8** %6, align 8
%7 = load %struct.clousure_type*, %struct.clousure_type** %2, align 8
call void @_ZN13clousure_type4copyERKS_(%struct.clousure_type* %3, %struct.clousure_type* %7)
ret void
}
添加了以下通行证,我是否需要更改任何添加任何,其中哪些可能导致问题?
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createInstructionCombiningPass());
FPM->add(llvm::createPromoteMemoryToRegisterPass());
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createLICMPass());
FPM->add(llvm::createLoopDeletionPass());
FPM->add(llvm::createLoopUnrollPass());
FPM->add(llvm::createSCCPPass());
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createInstructionCombiningPass());
FPM->add(llvm::createDeadStoreEliminationPass());
FPM->add(llvm::createAggressiveDCEPass());
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createTailCallEliminationPass());
编辑即使我删除了所有的通道我仍然得到错误!
目前看来问题出在以下函数 @"$static.159"
而不是该函数试图 load @"$static.159$stub_ptr"
。理论是它不能被删除,因为它正在尝试加载自己?
; Function Attrs: alwaysinline
define available_externally hidden void @"$static.159"(%struct.clousure_type*, %struct.clousure_type*) #0 {
entry:
%2 = load void (%struct.clousure_type*, %struct.clousure_type*)*, void (%struct.clousure_type*, %struct.clousure_type*)** @"$static.159$stub_ptr"
tail call void %2(%struct.clousure_type* %0, %struct.clousure_type* %1)
ret void
}
升级到 llvm 5.0 终于解决了这个错误。
这不是理论上的问题。简单地将我存储在函数指针中的函数之一放入,由于生成上述代码的 c++ 代码中的指针初始化不正确,导致上面找到 <badref>
,因此未进行分配。请注意,由于使用了函数指针,<badref>
只是后来被优化器找到的!!
我不知道为什么这个指针之前没有导致段错误,但它确实没有,允许错误的代码生成。在 llvm 5.0 上,指针按预期给出段错误,让我找到错误。
您好,我最近升级到了 llvm 4.0,现在我从优化器那里得到了最奇怪的错误,这似乎是最良性的代码。我已经确定了似乎给我以下错误的代码,以及 llvm 给我的关于 <badref>
的断言的打印输出,但是在它正在谈论的代码中看不到 <badref>
。这让我认为这可能是编译器错误或生成的代码不正确。
; ModuleID = '__form__module.$static.196'
source_filename = "__form__module.$static.196"
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
%struct.clousure_type = type { void ()*, %struct.closure_vtable*, i8* }
%struct.closure_vtable = type { %struct.type_info*, void (i8*, i8*)*, void (i8*)*, i8 (i8*, i8*)*, i64 (i8*, i8*)* }
%struct.type_info = type { i8*, i8*, i64, i8, i8, i8, i8, %struct.type_info**, %struct.member_info* }
%struct.member_info = type { i8, %struct.type_info* }
@"$static.159$stub_ptr" = external hidden externally_initialized global void (%struct.clousure_type*, %struct.clousure_type*)*
define hidden void @"$static.196"(%struct.clousure_type*, %struct.clousure_type*, %struct.clousure_type*, i8) {
entry:
%4 = icmp eq i8 %3, 0
br i1 %4, label %bb2, label %bb4
bb2: ; preds = %entry
%5 = icmp eq %struct.clousure_type* %0, %2
br i1 %5, label %bb3, label %bb6
bb3: ; preds = %bb4, %bb2
ret void
bb4: ; preds = %entry
%6 = icmp eq %struct.clousure_type* %1, %2
br i1 %6, label %bb3, label %bb6
bb6: ; preds = %bb4, %bb2
tail call void @"$static.159"(%struct.clousure_type* %0, %struct.clousure_type* %1)
ret void
}
; Function Attrs: alwaysinline
define available_externally hidden void @"$static.159"(%struct.clousure_type*, %struct.clousure_type*) #0 {
entry:
%2 = load void (%struct.clousure_type*, %struct.clousure_type*)*, void (%struct.clousure_type*, %struct.clousure_type*)** @"$static.159$stub_ptr", align 8
tail call void %2(%struct.clousure_type* %0, %struct.clousure_type* %1)
ret void
}
attributes #0 = { alwaysinline }
While deleting: void (%struct.clousure_type*, %struct.clousure_type*)* %$static.159
Use still stuck around after Def is destroyed: call void @"$static.159"(%struct.clousure_type* <badref>, %struct.clousure_type* %0)
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Assertion failed!
Program: C:\Users\RICH\workspace\formvm\Debug\formvm.exe
File: C:\llvm-4.0.0.src\lib\IR\Value.cpp, Line 85
Expression: use_empty() && "Uses remain when a value is destroyed!"
代表上述 2 个函数的优化器正在处理的 llvm ir 代码是以下 2 个函数(从 c++ 生成)。
define private void @gen__fun__return_copy85(%struct.clousure_type*, %struct.clousure_type*, %struct.clousure_type*, i8) {
entry:
%4 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %0, %struct.clousure_type** %4, align 8
%5 = load %struct.clousure_type*, %struct.clousure_type** %4, align 8
%6 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %1, %struct.clousure_type** %6, align 8
%7 = load %struct.clousure_type*, %struct.clousure_type** %6, align 8
%8 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %2, %struct.clousure_type** %8, align 8
%9 = load %struct.clousure_type*, %struct.clousure_type** %8, align 8
%10 = alloca i8, align 8
store i8 %3, i8* %10, align 8
%11 = load i8, i8* %10, align 8
%12 = icmp eq i8 %11, 0
br i1 %12, label %bb2, label %bb4
bb2: ; preds = %entry
%13 = icmp eq %struct.clousure_type* %5, %9
br i1 %13, label %bb3, label %bb6
bb3: ; preds = %bb2
ret void
bb4: ; preds = %entry
%14 = icmp eq %struct.clousure_type* %7, %9
br i1 %14, label %bb5, label %bb6
bb5: ; preds = %bb4
ret void
bb6: ; preds = %bb4, %bb2
call void @_ZN13clousure_typeC2ERKS_(%struct.clousure_type* %5, %struct.clousure_type* %7)
ret void
}
define private void @_ZN13clousure_typeC2ERKS_(%struct.clousure_type* %this, %struct.clousure_type* %rhs) {
%1 = alloca %struct.clousure_type*, align 8
%2 = alloca %struct.clousure_type*, align 8
store %struct.clousure_type* %this, %struct.clousure_type** %1, align 8
store %struct.clousure_type* %rhs, %struct.clousure_type** %2, align 8
%3 = load %struct.clousure_type*, %struct.clousure_type** %1, align 8
%4 = getelementptr %struct.clousure_type, %struct.clousure_type* %3, i32 0, i32 0
store void ()* null, void ()** %4, align 8
%5 = getelementptr %struct.clousure_type, %struct.clousure_type* %3, i32 0, i32 1
store %struct.closure_vtable* null, %struct.closure_vtable** %5, align 8
%6 = getelementptr %struct.clousure_type, %struct.clousure_type* %3, i32 0, i32 2
store i8* null, i8** %6, align 8
%7 = load %struct.clousure_type*, %struct.clousure_type** %2, align 8
call void @_ZN13clousure_type4copyERKS_(%struct.clousure_type* %3, %struct.clousure_type* %7)
ret void
}
添加了以下通行证,我是否需要更改任何添加任何,其中哪些可能导致问题?
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createInstructionCombiningPass());
FPM->add(llvm::createPromoteMemoryToRegisterPass());
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createLICMPass());
FPM->add(llvm::createLoopDeletionPass());
FPM->add(llvm::createLoopUnrollPass());
FPM->add(llvm::createSCCPPass());
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createInstructionCombiningPass());
FPM->add(llvm::createDeadStoreEliminationPass());
FPM->add(llvm::createAggressiveDCEPass());
FPM->add(llvm::createCFGSimplificationPass());
FPM->add(llvm::createTailCallEliminationPass());
编辑即使我删除了所有的通道我仍然得到错误!
目前看来问题出在以下函数 @"$static.159"
而不是该函数试图 load @"$static.159$stub_ptr"
。理论是它不能被删除,因为它正在尝试加载自己?
; Function Attrs: alwaysinline
define available_externally hidden void @"$static.159"(%struct.clousure_type*, %struct.clousure_type*) #0 {
entry:
%2 = load void (%struct.clousure_type*, %struct.clousure_type*)*, void (%struct.clousure_type*, %struct.clousure_type*)** @"$static.159$stub_ptr"
tail call void %2(%struct.clousure_type* %0, %struct.clousure_type* %1)
ret void
}
升级到 llvm 5.0 终于解决了这个错误。
这不是理论上的问题。简单地将我存储在函数指针中的函数之一放入,由于生成上述代码的 c++ 代码中的指针初始化不正确,导致上面找到 <badref>
,因此未进行分配。请注意,由于使用了函数指针,<badref>
只是后来被优化器找到的!!
我不知道为什么这个指针之前没有导致段错误,但它确实没有,允许错误的代码生成。在 llvm 5.0 上,指针按预期给出段错误,让我找到错误。