Index: lib/Transforms/Scalar/LoopUnrollPass.cpp =================================================================== --- lib/Transforms/Scalar/LoopUnrollPass.cpp +++ lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -384,6 +384,10 @@ if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) RHS = SimpleRHS; + if (!isa(LHS) && !isa(RHS)) + if (!simplifyUsingOffsets(LHS, RHS)) + return Base::visitBinaryOperator(I); + Value *SimpleV = nullptr; const DataLayout &DL = I.getModule()->getDataLayout(); if (auto FI = dyn_cast(&I)) @@ -436,6 +440,49 @@ return true; } + + bool visitCmpInst(CmpInst &I) { + Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); + + // 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 (!isa(LHS) && !isa(RHS)) + if (!simplifyUsingOffsets(LHS, RHS)) + return Base::visitCmpInst(I); + + 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 Base::visitCmpInst(I); + } + + /// \brief Check if \p LHS and \p RHS correspond to address expressions with + /// the same base and their offsets could be folded to constants. + /// + /// \returns true and updates \p LHS and \p RHS if they both are present in + /// SimplifiedAddresses and have the same base address. + bool simplifyUsingOffsets(Value *&LHS, Value *&RHS) { + if (!SimplifiedAddresses.count(LHS) || !SimplifiedAddresses.count(RHS)) + return false; + SimplifiedAddress LHSAddr = SimplifiedAddresses.lookup(LHS); + SimplifiedAddress RHSAddr = SimplifiedAddresses.lookup(RHS); + if (LHSAddr.Base != RHSAddr.Base) + return false; + LHS = LHSAddr.Offset; + RHS = RHSAddr.Offset; + return true; + } }; } // namespace @@ -525,6 +572,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()) { + if (Constant *SimpleCond = + SimplifiedValues.lookup(BI->getCondition())) { + BBWorklist.insert(BI->getSuccessor( + cast(SimpleCond)->isZero() ? 1 : 0)); + continue; + } + } + } else if (SwitchInst *SI = dyn_cast(TI)) { + if (Constant *SimpleCond = + SimplifiedValues.lookup(SI->getCondition())) { + BBWorklist.insert( + SI->getSuccessor(cast(SimpleCond)->getSExtValue())); + continue; + } + } + // Add BB's successors to the worklist. for (BasicBlock *Succ : successors(BB)) if (L->contains(Succ))