From 86102b8ad54820ea136106fc6ea29720ad1640ea Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 1 Jan 2005 16:22:27 +0000 Subject: [PATCH] This is a bulk commit that implements the following primary improvements: * We can now fold cast instructions into select instructions that have at least one constant operand. * We now optimize expressions more aggressively based on bits that are known to be zero. These optimizations occur a lot in code that uses bitfields even in simple ways. * We now turn more cast-cast sequences into AND instructions. Before we would only do this if it if all types were unsigned. Now only the middle type needs to be unsigned (guaranteeing a zero extend). * We transform sign extensions into zero extensions in several cases. This corresponds to these test/Regression/Transforms/InstCombine testcases: 2004-11-22-Missed-and-fold.ll and.ll: test28-29 cast.ll: test21-24 and-or-and.ll cast-cast-to-and.ll zeroext-and-reduce.ll llvm-svn: 19220 --- .../Scalar/InstructionCombining.cpp | 346 ++++++++++++++---- 1 file changed, 268 insertions(+), 78 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index f78a14d42739..98f9846624e3 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -486,31 +486,60 @@ struct AddMaskingAnd { } }; -static Value *FoldOperationIntoSelectOperand(Instruction &BI, Value *SO, +static Value *FoldOperationIntoSelectOperand(Instruction &I, Value *SO, InstCombiner *IC) { + if (isa(I)) { + if (Constant *SOC = dyn_cast(SO)) + return ConstantExpr::getCast(SOC, I.getType()); + + return IC->InsertNewInstBefore(new CastInst(SO, I.getType(), + SO->getName() + ".cast"), I); + } + // Figure out if the constant is the left or the right argument. - bool ConstIsRHS = isa(BI.getOperand(1)); - Constant *ConstOperand = cast(BI.getOperand(ConstIsRHS)); + bool ConstIsRHS = isa(I.getOperand(1)); + Constant *ConstOperand = cast(I.getOperand(ConstIsRHS)); if (Constant *SOC = dyn_cast(SO)) { if (ConstIsRHS) - return ConstantExpr::get(BI.getOpcode(), SOC, ConstOperand); - return ConstantExpr::get(BI.getOpcode(), ConstOperand, SOC); + return ConstantExpr::get(I.getOpcode(), SOC, ConstOperand); + return ConstantExpr::get(I.getOpcode(), ConstOperand, SOC); } Value *Op0 = SO, *Op1 = ConstOperand; if (!ConstIsRHS) std::swap(Op0, Op1); Instruction *New; - if (BinaryOperator *BO = dyn_cast(&BI)) - New = BinaryOperator::create(BO->getOpcode(), Op0, Op1); - else if (ShiftInst *SI = dyn_cast(&BI)) - New = new ShiftInst(SI->getOpcode(), Op0, Op1); + if (BinaryOperator *BO = dyn_cast(&I)) + New = BinaryOperator::create(BO->getOpcode(), Op0, Op1,SO->getName()+".op"); + else if (ShiftInst *SI = dyn_cast(&I)) + New = new ShiftInst(SI->getOpcode(), Op0, Op1, SO->getName()+".sh"); else { assert(0 && "Unknown binary instruction type!"); abort(); } - return IC->InsertNewInstBefore(New, BI); + return IC->InsertNewInstBefore(New, I); +} + +// FoldOpIntoSelect - Given an instruction with a select as one operand and a +// constant as the other operand, try to fold the binary operator into the +// select arguments. This also works for Cast instructions, which obviously do +// not have a second operand. +static Instruction *FoldOpIntoSelect(Instruction &Op, SelectInst *SI, + InstCombiner *IC) { + // Don't modify shared select instructions + if (!SI->hasOneUse()) return 0; + Value *TV = SI->getOperand(1); + Value *FV = SI->getOperand(2); + + if (isa(TV) || isa(FV)) { + Value *SelectTrueVal = FoldOperationIntoSelectOperand(Op, TV, IC); + Value *SelectFalseVal = FoldOperationIntoSelectOperand(Op, FV, IC); + + return new SelectInst(SI->getCondition(), SelectTrueVal, + SelectFalseVal); + } + return 0; } @@ -555,26 +584,6 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) { return ReplaceInstUsesWith(I, NewPN); } -// FoldBinOpIntoSelect - Given an instruction with a select as one operand and a -// constant as the other operand, try to fold the binary operator into the -// select arguments. -static Instruction *FoldBinOpIntoSelect(Instruction &BI, SelectInst *SI, - InstCombiner *IC) { - // Don't modify shared select instructions - if (!SI->hasOneUse()) return 0; - Value *TV = SI->getOperand(1); - Value *FV = SI->getOperand(2); - - if (isa(TV) || isa(FV)) { - Value *SelectTrueVal = FoldOperationIntoSelectOperand(BI, TV, IC); - Value *SelectFalseVal = FoldOperationIntoSelectOperand(BI, FV, IC); - - return new SelectInst(SI->getCondition(), SelectTrueVal, - SelectFalseVal); - } - return 0; -} - Instruction *InstCombiner::visitAdd(BinaryOperator &I) { bool Changed = SimplifyCommutative(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); @@ -667,10 +676,9 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { } } - // Try to fold constant add into select arguments. if (SelectInst *SI = dyn_cast(LHS)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; } @@ -761,7 +769,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { // Try to fold constant sub into select arguments. if (SelectInst *SI = dyn_cast(Op1)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) @@ -889,7 +897,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { // Try to fold constant mul into select arguments. if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) @@ -990,7 +998,7 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) { if (!RHS->isNullValue()) { if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) @@ -1066,7 +1074,7 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) { if (!RHS->isNullValue()) { if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) @@ -1251,6 +1259,70 @@ struct FoldSetCCLogical { }; +/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use +/// this predicate to simplify operations downstream. V and Mask are known to +/// be the same type. +static bool MaskedValueIsZero(Value *V, ConstantIntegral *Mask) { + if (isa(V) || Mask->isNullValue()) + return true; + if (ConstantIntegral *CI = dyn_cast(V)) + return ConstantExpr::getAnd(CI, Mask)->isNullValue(); + + if (Instruction *I = dyn_cast(V)) { + switch (I->getOpcode()) { + case Instruction::And: + // (X & C1) & C2 == 0 iff C1 & C2 == 0. + if (ConstantIntegral *CI = dyn_cast(I->getOperand(1))) + if (ConstantExpr::getAnd(CI, Mask)->isNullValue()) + return true; + break; + case Instruction::Cast: { + const Type *SrcTy = I->getOperand(0)->getType(); + if (SrcTy->isIntegral()) { + // (cast X to int) & C2 == 0 iff could not have contained C2. + if (SrcTy->isUnsigned() && // Only handle zero ext. + ConstantExpr::getCast(Mask, SrcTy)->isNullValue()) + return true; + + // If this is a noop cast, recurse. + if (SrcTy != Type::BoolTy) + if ((SrcTy->isSigned() && SrcTy->getUnsignedVersion() ==I->getType()) || + SrcTy->getSignedVersion() == I->getType()) { + Constant *NewMask = + ConstantExpr::getCast(Mask, I->getOperand(0)->getType()); + return MaskedValueIsZero(I->getOperand(0), + cast(NewMask)); + } + } + break; + } + case Instruction::Shl: + // (shl X, C1) & C2 == 0 iff (-1 << C1) & C2 == 0 + if (ConstantUInt *SA = dyn_cast(I->getOperand(1))) { + Constant *C1 = ConstantIntegral::getAllOnesValue(I->getType()); + C1 = ConstantExpr::getShl(C1, SA); + C1 = ConstantExpr::getAnd(C1, Mask); + if (C1->isNullValue()) + return true; + } + break; + case Instruction::Shr: + // (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0 + if (ConstantUInt *SA = dyn_cast(I->getOperand(1))) + if (I->getType()->isUnsigned()) { + Constant *C1 = ConstantIntegral::getAllOnesValue(I->getType()); + C1 = ConstantExpr::getShr(C1, SA); + C1 = ConstantExpr::getAnd(C1, Mask); + if (C1->isNullValue()) + return true; + } + break; + } + } + + return false; +} + // OptAndOp - This handles expressions of the form ((val OP C1) & C2). Where // the Op parameter is 'OP', OpRHS is 'C1', and AndRHS is 'C2'. Op is // guaranteed to be either a shift instruction or a binary operator. @@ -1265,10 +1337,7 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op, switch (Op->getOpcode()) { case Instruction::Xor: - if (Together->isNullValue()) { - // (X ^ C1) & C2 --> (X & C2) iff (C1&C2) == 0 - return BinaryOperator::createAnd(X, AndRHS); - } else if (Op->hasOneUse()) { + if (Op->hasOneUse()) { // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) std::string OpName = Op->getName(); Op->setName(""); Instruction *And = BinaryOperator::createAnd(X, AndRHS, OpName); @@ -1277,20 +1346,15 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op, } break; case Instruction::Or: - // (X | C1) & C2 --> X & C2 iff C1 & C1 == 0 - if (Together->isNullValue()) - return BinaryOperator::createAnd(X, AndRHS); - else { - if (Together == AndRHS) // (X | C) & C --> C - return ReplaceInstUsesWith(TheAnd, AndRHS); + if (Together == AndRHS) // (X | C) & C --> C + return ReplaceInstUsesWith(TheAnd, AndRHS); - if (Op->hasOneUse() && Together != OpRHS) { - // (X | C1) & C2 --> (X | (C1&C2)) & C2 - std::string Op0Name = Op->getName(); Op->setName(""); - Instruction *Or = BinaryOperator::createOr(X, Together, Op0Name); - InsertNewInstBefore(Or, TheAnd); - return BinaryOperator::createAnd(Or, AndRHS); - } + if (Op->hasOneUse() && Together != OpRHS) { + // (X | C1) & C2 --> (X | (C1&C2)) & C2 + std::string Op0Name = Op->getName(); Op->setName(""); + Instruction *Or = BinaryOperator::createOr(X, Together, Op0Name); + InsertNewInstBefore(Or, TheAnd); + return BinaryOperator::createAnd(Or, AndRHS); } break; case Instruction::Add: @@ -1445,27 +1509,103 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (isa(Op1)) // X & undef -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - // and X, X = X and X, 0 == 0 - if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType())) + // and X, X = X + if (Op0 == Op1) return ReplaceInstUsesWith(I, Op1); // and X, -1 == X - if (ConstantIntegral *RHS = dyn_cast(Op1)) { - if (RHS->isAllOnesValue()) + if (ConstantIntegral *AndRHS = dyn_cast(Op1)) { + if (AndRHS->isAllOnesValue()) // and X, -1 == X return ReplaceInstUsesWith(I, Op0); + if (MaskedValueIsZero(Op0, AndRHS)) // LHS & RHS == 0 + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + + // If the mask is not masking out any bits, there is no reason to do the + // and in the first place. + if (MaskedValueIsZero(Op0, + cast(ConstantExpr::getNot(AndRHS)))) + return ReplaceInstUsesWith(I, Op0); + // Optimize a variety of ((val OP C1) & C2) combinations... if (isa(Op0) || isa(Op0)) { Instruction *Op0I = cast(Op0); - Value *X = Op0I->getOperand(0); + Value *Op0LHS = Op0I->getOperand(0); + Value *Op0RHS = Op0I->getOperand(1); + switch (Op0I->getOpcode()) { + case Instruction::Xor: + case Instruction::Or: + // (X ^ V) & C2 --> (X & C2) iff (V & C2) == 0 + // (X | V) & C2 --> (X & C2) iff (V & C2) == 0 + if (MaskedValueIsZero(Op0LHS, AndRHS)) + return BinaryOperator::createAnd(Op0RHS, AndRHS); + if (MaskedValueIsZero(Op0RHS, AndRHS)) + return BinaryOperator::createAnd(Op0LHS, AndRHS); + break; + case Instruction::And: + // (X & V) & C2 --> 0 iff (V & C2) == 0 + if (MaskedValueIsZero(Op0LHS, AndRHS) || + MaskedValueIsZero(Op0RHS, AndRHS)) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + break; + } + if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) - if (Instruction *Res = OptAndOp(Op0I, Op0CI, RHS, I)) + if (Instruction *Res = OptAndOp(Op0I, Op0CI, AndRHS, I)) return Res; + } else if (CastInst *CI = dyn_cast(Op0)) { + const Type *SrcTy = CI->getOperand(0)->getType(); + + // If this is an integer sign or zero extension instruction. + if (SrcTy->isIntegral() && + SrcTy->getPrimitiveSize() < CI->getType()->getPrimitiveSize()) { + + if (SrcTy->isUnsigned()) { + // See if this and is clearing out bits that are known to be zero + // anyway (due to the zero extension). + Constant *Mask = ConstantIntegral::getAllOnesValue(SrcTy); + Mask = ConstantExpr::getZeroExtend(Mask, CI->getType()); + Constant *Result = ConstantExpr::getAnd(Mask, AndRHS); + if (Result == Mask) // The "and" isn't doing anything, remove it. + return ReplaceInstUsesWith(I, CI); + if (Result != AndRHS) { // Reduce the and RHS constant. + I.setOperand(1, Result); + return &I; + } + + } else { + if (CI->hasOneUse() && SrcTy->isInteger()) { + // We can only do this if all of the sign bits brought in are masked + // out. Compute this by first getting 0000011111, then inverting + // it. + Constant *Mask = ConstantIntegral::getAllOnesValue(SrcTy); + Mask = ConstantExpr::getZeroExtend(Mask, CI->getType()); + Mask = ConstantExpr::getNot(Mask); // 1's in the new bits. + if (ConstantExpr::getAnd(Mask, AndRHS)->isNullValue()) { + // If the and is clearing all of the sign bits, change this to a + // zero extension cast. To do this, cast the cast input to + // unsigned, then to the requested size. + Value *CastOp = CI->getOperand(0); + Instruction *NC = + new CastInst(CastOp, CastOp->getType()->getUnsignedVersion(), + CI->getName()+".uns"); + NC = InsertNewInstBefore(NC, I); + // Finally, insert a replacement for CI. + NC = new CastInst(NC, CI->getType(), CI->getName()); + CI->setName(""); + NC = InsertNewInstBefore(NC, I); + WorkList.push_back(CI); // Delete CI later. + I.setOperand(0, NC); + return &I; // The AND operand was modified. + } + } + } + } } // Try to fold constant and into select arguments. if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) @@ -1599,8 +1739,11 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { // or X, -1 == -1 if (ConstantIntegral *RHS = dyn_cast(Op1)) { - if (RHS->isAllOnesValue()) - return ReplaceInstUsesWith(I, Op1); + // If X is known to only contain bits that already exist in RHS, just + // replace this instruction with RHS directly. + if (MaskedValueIsZero(Op0, + cast(ConstantExpr::getNot(RHS)))) + return ReplaceInstUsesWith(I, RHS); ConstantInt *C1; Value *X; // (X & C1) | C2 --> (X | C2) & (C1|C2) @@ -1622,7 +1765,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { // Try to fold constant and into select arguments. if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) @@ -1840,7 +1983,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { // Try to fold constant and into select arguments. if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) @@ -2671,7 +2814,7 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) { // Try to fold constant and into select arguments. if (isa(Op0)) if (SelectInst *SI = dyn_cast(Op1)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (ConstantUInt *CUI = dyn_cast(Op1)) { @@ -2697,15 +2840,48 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) { // Try to fold constant and into select arguments. if (SelectInst *SI = dyn_cast(Op0)) - if (Instruction *R = FoldBinOpIntoSelect(I, SI, this)) + if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; if (isa(Op0)) if (Instruction *NV = FoldOpIntoPhi(I)) return NV; - // If the operand is an bitwise operator with a constant RHS, and the - // shift is the only use, we can pull it out of the shift. - if (Op0->hasOneUse()) + if (Op0->hasOneUse()) { + // If this is a SHL of a sign-extending cast, see if we can turn the input + // into a zero extending cast (a simple strength reduction). + if (CastInst *CI = dyn_cast(Op0)) { + const Type *SrcTy = CI->getOperand(0)->getType(); + if (isLeftShift && SrcTy->isInteger() && SrcTy->isSigned() && + SrcTy->getPrimitiveSize() < CI->getType()->getPrimitiveSize()) { + // We can change it to a zero extension if we are shifting out all of + // the sign extended bits. To check this, form a mask of all of the + // sign extend bits, then shift them left and see if we have anything + // left. + Constant *Mask = ConstantIntegral::getAllOnesValue(SrcTy); // 1111 + Mask = ConstantExpr::getZeroExtend(Mask, CI->getType()); // 00001111 + Mask = ConstantExpr::getNot(Mask); // 1's in the sign bits: 11110000 + if (ConstantExpr::getShl(Mask, CUI)->isNullValue()) { + // If the shift is nuking all of the sign bits, change this to a + // zero extension cast. To do this, cast the cast input to + // unsigned, then to the requested size. + Value *CastOp = CI->getOperand(0); + Instruction *NC = + new CastInst(CastOp, CastOp->getType()->getUnsignedVersion(), + CI->getName()+".uns"); + NC = InsertNewInstBefore(NC, I); + // Finally, insert a replacement for CI. + NC = new CastInst(NC, CI->getType(), CI->getName()); + CI->setName(""); + NC = InsertNewInstBefore(NC, I); + WorkList.push_back(CI); // Delete CI later. + I.setOperand(0, NC); + return &I; // The SHL operand was modified. + } + } + } + + // If the operand is an bitwise operator with a constant RHS, and the + // shift is the only use, we can pull it out of the shift. if (BinaryOperator *Op0BO = dyn_cast(Op0)) if (ConstantInt *Op0C = dyn_cast(Op0BO->getOperand(1))) { bool isValid = true; // Valid only for And, Or, Xor @@ -2749,6 +2925,7 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) { NewRHS); } } + } // If this is a shift of a shift, see if we can fold the two together... if (ShiftInst *Op0SI = dyn_cast(Op0)) @@ -2926,9 +3103,10 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { // If casting the result of another cast instruction, try to eliminate this // one! // - if (CastInst *CSrc = dyn_cast(Src)) { - if (isEliminableCastOfCast(CSrc->getOperand(0)->getType(), - CSrc->getType(), CI.getType(), TD)) { + if (CastInst *CSrc = dyn_cast(Src)) { // A->B->C cast + Value *A = CSrc->getOperand(0); + if (isEliminableCastOfCast(A->getType(), CSrc->getType(), + CI.getType(), TD)) { // This instruction now refers directly to the cast's src operand. This // has a good chance of making CSrc dead. CI.setOperand(0, CSrc->getOperand(0)); @@ -2938,18 +3116,27 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { // If this is an A->B->A cast, and we are dealing with integral types, try // to convert this into a logical 'and' instruction. // - if (CSrc->getOperand(0)->getType() == CI.getType() && + if (A->getType()->isInteger() && CI.getType()->isInteger() && CSrc->getType()->isInteger() && - CI.getType()->isUnsigned() && CSrc->getType()->isUnsigned() && - CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()){ + CSrc->getType()->isUnsigned() && // B->A cast must zero extend + CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()&& + A->getType()->getPrimitiveSize() == CI.getType()->getPrimitiveSize()) { assert(CSrc->getType() != Type::ULongTy && "Cannot have type bigger than ulong!"); uint64_t AndValue = (1ULL << CSrc->getType()->getPrimitiveSize()*8)-1; - Constant *AndOp = ConstantUInt::get(CI.getType(), AndValue); - return BinaryOperator::createAnd(CSrc->getOperand(0), AndOp); + Constant *AndOp = ConstantUInt::get(A->getType()->getUnsignedVersion(), + AndValue); + AndOp = ConstantExpr::getCast(AndOp, A->getType()); + Instruction *And = BinaryOperator::createAnd(CSrc->getOperand(0), AndOp); + if (And->getType() != CI.getType()) { + And->setName(CSrc->getName()+".mask"); + InsertNewInstBefore(And, CI); + And = new CastInst(And, CI.getType()); + } + return And; } } - + // If this is a cast to bool, turn it into the appropriate setne instruction. if (CI.getType() == Type::BoolTy) return BinaryOperator::createSetNE(CI.getOperand(0), @@ -3001,6 +3188,9 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { } } + if (SelectInst *SI = dyn_cast(Src)) + if (Instruction *NV = FoldOpIntoSelect(CI, SI, this)) + return NV; if (isa(Src)) if (Instruction *NV = FoldOpIntoPhi(CI)) return NV;