Index: lib/Transforms/Scalar/NewGVN.cpp =================================================================== --- lib/Transforms/Scalar/NewGVN.cpp +++ lib/Transforms/Scalar/NewGVN.cpp @@ -689,8 +689,15 @@ // return it. Otherwise, return the operand itself. Value *NewGVN::lookupOperandLeader(Value *V) const { CongruenceClass *CC = ValueToClass.lookup(V); - if (CC && (CC != InitialClass)) + if (CC) { + // Everything in INITIAL is represneted by undef, as it can be any value. + // We do have to make sure we get the type right though, so we can't set the + // RepLeader to undef. + if (CC == InitialClass) + return UndefValue::get(V->getType()); return CC->RepStoredValue ? CC->RepStoredValue : CC->RepLeader; + } + return V; } @@ -964,9 +971,8 @@ // expression. assert(II->getNumArgOperands() == 2 && "Expect two args for recognised intrinsics."); - return createBinaryExpression(Opcode, EI->getType(), - II->getArgOperand(0), - II->getArgOperand(1)); + return createBinaryExpression( + Opcode, EI->getType(), II->getArgOperand(0), II->getArgOperand(1)); } } } @@ -1207,7 +1213,7 @@ } // We don't need to sort members if there is only 1, and we don't care about - // sorting the initial class because everything either gets out of it or is + // sorting the INITIAL class because everything either gets out of it or is // unreachable. if (OldClass->Members.size() == 1 || OldClass == InitialClass) { OldClass->RepLeader = *(OldClass->Members.begin()); @@ -1236,7 +1242,7 @@ void NewGVN::performCongruenceFinding(Instruction *I, const Expression *E) { ValueToExpression[I] = E; // This is guaranteed to return something, since it will at least find - // INITIAL. + // TOP. CongruenceClass *IClass = ValueToClass[I]; assert(IClass && "Should have found a IClass"); @@ -1425,8 +1431,7 @@ } // The algorithm initially places the values of the routine in the INITIAL -// congruence -// class. The leader of INITIAL is the undetermined value `TOP`. +// congruence class. The leader of INITIAL is the undetermined value `TOP`. // When the algorithm has finished, values still in INITIAL are unreachable. void NewGVN::initializeCongruenceClasses(Function &F) { // FIXME now i can't remember why this is 2 @@ -1440,8 +1445,11 @@ MemoryAccessToClass[MP] = InitialClass; for (auto &I : B) { - InitialValues.insert(&I); - ValueToClass[&I] = InitialClass; + // Don't insert void terminators into the class + if (!isa(I) || !I.getType()->isVoidTy()) { + InitialValues.insert(&I); + ValueToClass[&I] = InitialClass; + } // All memory accesses are equivalent to live on entry to start. They must // be initialized to something so that initial changes are noticed. For // the maximal answer, we initialize them all to be the same as @@ -1592,7 +1600,8 @@ performCongruenceFinding(I, Symbolized); } else { // Handle terminators that return values. All of them produce values we - // don't currently understand. + // don't currently understand. We don't place non-value producing + // terminators in a class. if (!I->getType()->isVoidTy()) { auto *Symbolized = createUnknownExpression(I); performCongruenceFinding(I, Symbolized); @@ -2205,12 +2214,19 @@ // dead store elimination. SmallVector PossibleDeadStores; - // FIXME: We should eventually be able to replace everything still - // in the initial class with undef, as they should be unreachable. - // Right now, initial still contains some things we skip value - // numbering of (UNREACHABLE's, for example). - if (CC == InitialClass || CC->Dead) + if (CC->Dead) continue; + // Everything still in the INITIAL class is unreachable or dead. + if (CC == InitialClass) { + // Assert everything is unreachable or dead + for (auto M : CC->Members) + assert((!ReachableBlocks.count(cast(M)->getParent()) || + InstructionsToErase.count(cast(M))) && + "Everything in INITIAL should be unreachable or dead at this " + "point"); + continue; + } + assert(CC->RepLeader && "We should have had a leader"); // If this is a leader that is always available, and it's a