@@ -8012,10 +8012,20 @@ class HorizontalReduction {
80128012 Value *RHS, const Twine &Name, bool UseSelect) {
80138013 unsigned RdxOpcode = RecurrenceDescriptor::getOpcode (Kind);
80148014 switch (Kind) {
8015- case RecurKind::Add:
8016- case RecurKind::Mul:
80178015 case RecurKind::Or:
8016+ if (UseSelect &&
8017+ LHS->getType () == CmpInst::makeCmpResultType (LHS->getType ()))
8018+ return Builder.CreateSelect (LHS, Builder.getTrue (), RHS, Name);
8019+ return Builder.CreateBinOp ((Instruction::BinaryOps)RdxOpcode, LHS, RHS,
8020+ Name);
80188021 case RecurKind::And:
8022+ if (UseSelect &&
8023+ LHS->getType () == CmpInst::makeCmpResultType (LHS->getType ()))
8024+ return Builder.CreateSelect (LHS, RHS, Builder.getFalse (), Name);
8025+ return Builder.CreateBinOp ((Instruction::BinaryOps)RdxOpcode, LHS, RHS,
8026+ Name);
8027+ case RecurKind::Add:
8028+ case RecurKind::Mul:
80198029 case RecurKind::Xor:
80208030 case RecurKind::FAdd:
80218031 case RecurKind::FMul:
@@ -8059,8 +8069,12 @@ class HorizontalReduction {
80598069 static Value *createOp (IRBuilder<> &Builder, RecurKind RdxKind, Value *LHS,
80608070 Value *RHS, const Twine &Name,
80618071 const ReductionOpsListType &ReductionOps) {
8062- bool UseSelect = ReductionOps.size () == 2 ;
8063- assert ((!UseSelect || isa<SelectInst>(ReductionOps[1 ][0 ])) &&
8072+ bool UseSelect = ReductionOps.size () == 2 ||
8073+ // Logical or/and.
8074+ (ReductionOps.size () == 1 &&
8075+ isa<SelectInst>(ReductionOps.front ().front ()));
8076+ assert ((!UseSelect || ReductionOps.size () != 2 ||
8077+ isa<SelectInst>(ReductionOps[1 ][0 ])) &&
80648078 " Expected cmp + select pairs for reduction" );
80658079 Value *Op = createOp (Builder, RdxKind, LHS, RHS, Name, UseSelect);
80668080 if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind (RdxKind)) {
@@ -8198,10 +8212,10 @@ class HorizontalReduction {
81988212 // / Checks if the instruction is in basic block \p BB.
81998213 // / For a cmp+sel min/max reduction check that both ops are in \p BB.
82008214 static bool hasSameParent (Instruction *I, BasicBlock *BB) {
8201- if (isCmpSelMinMax (I)) {
8215+ if (isCmpSelMinMax (I) || ( isBoolLogicOp (I) && isa<SelectInst>(I)) ) {
82028216 auto *Sel = cast<SelectInst>(I);
8203- auto *Cmp = cast <Instruction>(Sel->getCondition ());
8204- return Sel->getParent () == BB && Cmp->getParent () == BB;
8217+ auto *Cmp = dyn_cast <Instruction>(Sel->getCondition ());
8218+ return Sel->getParent () == BB && Cmp && Cmp ->getParent () == BB;
82058219 }
82068220 return I->getParent () == BB;
82078221 }
0 commit comments