@@ -8012,10 +8012,20 @@ class HorizontalReduction {
8012
8012
Value *RHS, const Twine &Name, bool UseSelect) {
8013
8013
unsigned RdxOpcode = RecurrenceDescriptor::getOpcode (Kind);
8014
8014
switch (Kind) {
8015
- case RecurKind::Add:
8016
- case RecurKind::Mul:
8017
8015
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);
8018
8021
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:
8019
8029
case RecurKind::Xor:
8020
8030
case RecurKind::FAdd:
8021
8031
case RecurKind::FMul:
@@ -8059,8 +8069,12 @@ class HorizontalReduction {
8059
8069
static Value *createOp (IRBuilder<> &Builder, RecurKind RdxKind, Value *LHS,
8060
8070
Value *RHS, const Twine &Name,
8061
8071
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 ])) &&
8064
8078
" Expected cmp + select pairs for reduction" );
8065
8079
Value *Op = createOp (Builder, RdxKind, LHS, RHS, Name, UseSelect);
8066
8080
if (RecurrenceDescriptor::isIntMinMaxRecurrenceKind (RdxKind)) {
@@ -8198,10 +8212,10 @@ class HorizontalReduction {
8198
8212
// / Checks if the instruction is in basic block \p BB.
8199
8213
// / For a cmp+sel min/max reduction check that both ops are in \p BB.
8200
8214
static bool hasSameParent (Instruction *I, BasicBlock *BB) {
8201
- if (isCmpSelMinMax (I)) {
8215
+ if (isCmpSelMinMax (I) || ( isBoolLogicOp (I) && isa<SelectInst>(I)) ) {
8202
8216
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;
8205
8219
}
8206
8220
return I->getParent () == BB;
8207
8221
}
0 commit comments