diff options
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 18 | ||||
-rw-r--r-- | test/Transforms/GVN/2012-05-22-PreCrash.ll | 33 |
2 files changed, 45 insertions, 6 deletions
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 915871e3c2..09aff1b3b3 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -557,12 +557,12 @@ namespace { } /// removeFromLeaderTable - Scan the list of values corresponding to a given - /// value number, and remove the given value if encountered. - void removeFromLeaderTable(uint32_t N, Value *V, BasicBlock *BB) { + /// value number, and remove the given instruction if encountered. + void removeFromLeaderTable(uint32_t N, Instruction *I, BasicBlock *BB) { LeaderTableEntry* Prev = 0; LeaderTableEntry* Curr = &LeaderTable[N]; - while (Curr->Val != V || Curr->BB != BB) { + while (Curr->Val != I || Curr->BB != BB) { Prev = Curr; Curr = Curr->Next; } @@ -2021,9 +2021,15 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, BasicBlock *Root) { DT->properlyDominates(cast<Instruction>(RHS)->getParent(), Root)) && "Instruction doesn't dominate scope!"); - // If value numbering later deduces that an instruction in the scope is equal - // to 'LHS' then ensure it will be turned into 'RHS'. - addToLeaderTable(LVN, RHS, Root); + // If value numbering later sees that an instruction in the scope is equal + // to 'LHS' then ensure it will be turned into 'RHS'. In order to preserve + // the invariant that instructions only occur in the leader table for their + // own value number (this is used by removeFromLeaderTable), do not do this + // if RHS is an instruction (if an instruction in the scope is morphed into + // LHS then it will be turned into RHS by the next GVN iteration anyway, so + // using the leader table is about compiling faster, not optimizing better). + if (!isa<Instruction>(RHS)) + addToLeaderTable(LVN, RHS, Root); // Replace all occurrences of 'LHS' with 'RHS' everywhere in the scope. As // LHS always has at least one use that is not dominated by Root, this will diff --git a/test/Transforms/GVN/2012-05-22-PreCrash.ll b/test/Transforms/GVN/2012-05-22-PreCrash.ll new file mode 100644 index 0000000000..b488dda9c3 --- /dev/null +++ b/test/Transforms/GVN/2012-05-22-PreCrash.ll @@ -0,0 +1,33 @@ +; RUN: opt < %s -gvn +; PR12858 + +define void @fn5(i16 signext %p1, i8 signext %p2) nounwind uwtable { +entry: + br i1 undef, label %if.else, label %if.then + +if.then: ; preds = %entry + br label %if.end + +if.else: ; preds = %entry + %conv = sext i16 %p1 to i32 + br label %if.end + +if.end: ; preds = %if.else, %if.then + %conv1 = sext i16 %p1 to i32 + br i1 undef, label %if.then3, label %if.else4 + +if.then3: ; preds = %if.end + br label %if.end12 + +if.else4: ; preds = %if.end + %conv7 = sext i8 %p2 to i32 + %cmp8 = icmp eq i32 %conv1, %conv7 + br i1 %cmp8, label %if.then10, label %if.end12 + +if.then10: ; preds = %if.else4 + br label %if.end12 + +if.end12: ; preds = %if.then10, %if.else4, %if.then3 + %conv13 = sext i8 %p2 to i32 + ret void +} |