2017-12-02 10 views
0

Hallo Ich habe vor kurzem auf llvm 4.0 aktualisiert und jetzt bekomme ich die seltsamsten Fehler aus dem Optimierer bei, was scheint der gütigste Code zu sein. Ich habe den Code identifiziert, der mir den Fehler unten zu geben scheint, und das Ausdrucken der Behauptung, dass llvm mich zu einem <badref> aber no <badref> betrifft, ist in dem Code sichtbar, über den es spricht. Das lässt mich denken, dass es ein Compilerfehler sein könnte oder der generierte Code falsch ist.llvm ir Optimierung "Verwenden Sie immer noch herum, nachdem Def zerstört wird" Fehler Funktion Löschen

; 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!" 

llvm Der IR-Code, die der Optimierer auf arbeitet, dass die oben genannten 2-Funktionen darstellen, sind die folgenden 2-Funktionen (von C++ erzeugt).

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 
} 

Um die folgenden Pässe hinzugefügt werden, muss ich irgendwelche hinzufügen hinzufügen, welche von diesen möglicherweise das Problem verursacht?

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()); 

Bearbeiten, auch wenn ich alle Pässe entfernen, bekomme ich immer noch den Fehler!

Im Moment scheint das Problem von der folgenden Funktion @"$static.159" nicht, dass die Funktion versucht, load @"$static.159$stub_ptr". Die Theorie ist, dass es nicht entfernt werden kann, während es versucht, sich zu laden?

; 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 
} 

Antwort

0

Es dauerte ein Upgrade auf llvm 5.0, um endlich einen Fehler zu bekommen.

Es war nicht der theoretischen Probleme. Einfach in eine der Funktionen, die ich in einem Funktionszeiger gespeichert hatte, wurde eine Zuweisung aufgrund eines falsch initialisierten Zeigers in dem C++ - Code, der den obigen Code erzeugte, der zu einer <badref> oben gefunden wurde, gemacht. Beachten Sie, dass das <badref> erst später vom Optimierer gefunden wurde, da Funktionszeiger verwendet wurden !!

Warum dieser Zeiger früher keinen segfault verursachte, weiß ich nicht, aber es tat nicht, erlaubend die falsche Codeerzeugung. Auf llvm 5.0 gibt der Zeiger wie erwartet einen segfault, der es mir ermöglicht, den Fehler zu finden.