diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 91a1b61ddc483..dd03ab8f08f85 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1738,14 +1738,17 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI, if (SI->getType()->isIntOrIntVectorTy(1)) return nullptr; - // Avoid breaking min/max reduction pattern, + // Avoid breaking reduction pattern, // which is necessary for vectorization later. - if (isa(&Op)) - for (Value *IntrinOp : Op.operands()) - if (auto *PN = dyn_cast(IntrinOp)) - for (Value *PhiOp : PN->operands()) - if (PhiOp == &Op) - return nullptr; + PHINode *PhiNode; + Value *Start, *Step; + if (auto *BinOp = dyn_cast(&Op)) { + if (matchSimpleRecurrence(BinOp, PhiNode, Start, Step)) + return nullptr; + } else if (auto *II = dyn_cast(&Op)) { + if (matchSimpleBinaryIntrinsicRecurrence(II, PhiNode, Start, Step)) + return nullptr; + } // Test if a FCmpInst instruction is used exclusively by a select as // part of a minimum or maximum operation. If so, refrain from doing