Index: lib/Transforms/Scalar/LoopUnrollPass.cpp =================================================================== --- lib/Transforms/Scalar/LoopUnrollPass.cpp +++ lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -361,6 +361,8 @@ if (SCEVSimplify(&I)) return true; Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); + if (!hasSamePointerBase(LHS, RHS)) + return false; if (!isa(LHS)) if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) LHS = SimpleLHS; @@ -421,6 +423,53 @@ return true; } + + bool visitCmpInst(CmpInst &I) { + if (SCEVSimplify(&I)) + return true; + Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); + if (!hasSamePointerBase(LHS, RHS)) + return false; + + // First try to handle simplified comparisons. + if (!isa(LHS)) + if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) + LHS = SimpleLHS; + if (!isa(RHS)) + if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) + RHS = SimpleRHS; + if (Constant *CLHS = dyn_cast(LHS)) { + if (Constant *CRHS = dyn_cast(RHS)) + if (Constant *C = ConstantExpr::getCompare(I.getPredicate(), CLHS, CRHS)) { + SimplifiedValues[&I] = C; + return true; + } + } + + return false; + } + + /// \brief Check if \p LHS and \p RHS has either the same pointer base, or + /// don't have it at all. + /// + /// If \p LHS and \p RHS are GEP-instructions, compare their base pointers + /// saved in GEPPointerBases map. They should be either the same, or be absent + /// for both values. + /// If both values aren't GEPs, \return true. + /// This check is necessary, because for GEPs with a base pointer + /// SimplifiedValues contains constant offset, and for GEPs without a base + /// pointer we save its plain value (constant). It's incorrect to compare + /// simplified values for GEPs of these two different kinds. + bool hasSamePointerBase(Value *LHS, Value *RHS) { + Value *LHSBase = nullptr, *RHSBase = nullptr; + GetElementPtrInst *LHSGEP = dyn_cast(LHS); + GetElementPtrInst *RHSGEP = dyn_cast(RHS); + if (LHSGEP) + LHSBase = GEPPointerBases.lookup(LHSGEP); + if (RHSGEP) + RHSBase = GEPPointerBases.lookup(RHSGEP); + return LHSBase == RHSBase; + } }; } // namespace @@ -499,6 +548,28 @@ return None; } + TerminatorInst *TI = BB->getTerminator(); + + // Add in the live successors by first checking whether we have terminator + // that may be simplified based on the values simplified by this call. + if (BranchInst *BI = dyn_cast(TI)) { + if (BI->isConditional()) { + Value *Cond = BI->getCondition(); + if (ConstantInt *SimpleCond + = dyn_cast_or_null(SimplifiedValues.lookup(Cond))) { + BBWorklist.insert(BI->getSuccessor(SimpleCond->isZero() ? 1 : 0)); + continue; + } + } + } else if (SwitchInst *SI = dyn_cast(TI)) { + Value *Cond = SI->getCondition(); + if (ConstantInt *SimpleCond + = dyn_cast_or_null(SimplifiedValues.lookup(Cond))) { + BBWorklist.insert(SI->findCaseValue(SimpleCond).getCaseSuccessor()); + continue; + } + } + // Add BB's successors to the worklist. for (BasicBlock *Succ : successors(BB)) if (L->contains(Succ))