Index: lib/Analysis/LazyValueInfo.cpp =================================================================== --- lib/Analysis/LazyValueInfo.cpp +++ lib/Analysis/LazyValueInfo.cpp @@ -1401,6 +1401,14 @@ return LVILatticeVal::getOverdefined(); } +// Return true if the instruction type of Val is supported by +// constantFoldUser(). Currently CastInst and BinaryOperator only. Call this +// before calling constantFoldUser() to find out if it's even worth attempting +// to call it. +static bool canConstantFoldUser(Value *Val) { + return isa(Val) || isa(Val); +} + /// \brief Compute the value of Val on the edge BBFrom -> BBTo. Returns false if /// Val is not constrained on the edge. Result is unspecified if return value /// is false. @@ -1436,7 +1444,7 @@ assert(Result.isOverdefined() && "Result isn't overdefined"); if (isa(Val->getType())) { const DataLayout &DL = BBTo->getModule()->getDataLayout(); - if (usesOperand(Usr, Condition)) { + if (canConstantFoldUser(Val) && usesOperand(Usr, Condition)) { // If Val has Condition as an operand and Val can be folded into a // constant with either Condition == true or Condition == false, // propagate the constant. @@ -1454,13 +1462,18 @@ // %Val = add i8 %Op, 1 // %Condition = icmp eq i8 %Op, 93 // br i1 %Condition, label %then, label %else - for (unsigned i = 0; i < Usr->getNumOperands(); ++i) { - Value *Op = Usr->getOperand(i); - LVILatticeVal OpLatticeVal = - getValueFromCondition(Op, Condition, isTrueDest); - if (Optional OpConst = OpLatticeVal.asConstantInteger()) { - Result = constantFoldUser(Val, Op, OpConst.getValue(), DL); - break; + // Check with canConstantFoldUser() first to avoid checking the + // operands which can be expensive for a large phi, etc. + if (canConstantFoldUser(Val)) { + for (unsigned i = 0; i < Usr->getNumOperands(); ++i) { + Value *Op = Usr->getOperand(i); + LVILatticeVal OpLatticeVal = + getValueFromCondition(Op, Condition, isTrueDest); + if (Optional OpConst = + OpLatticeVal.asConstantInteger()) { + Result = constantFoldUser(Val, Op, OpConst.getValue(), DL); + break; + } } } }