@@ -62,6 +62,8 @@ bool RecurrenceDescriptor::isIntegerRecurrenceKind(RecurKind Kind) {
62
62
case RecurKind::SMin:
63
63
case RecurKind::UMax:
64
64
case RecurKind::UMin:
65
+ case RecurKind::SelectICmp:
66
+ case RecurKind::SelectFCmp:
65
67
return true ;
66
68
}
67
69
return false ;
@@ -327,7 +329,8 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
327
329
// the starting value (the Phi or an AND instruction if the Phi has been
328
330
// type-promoted).
329
331
if (Cur != Start) {
330
- ReduxDesc = isRecurrenceInstr (Cur, Kind, ReduxDesc, FuncFMF);
332
+ ReduxDesc =
333
+ isRecurrenceInstr (TheLoop, Phi, Cur, Kind, ReduxDesc, FuncFMF);
331
334
if (!ReduxDesc.isRecurrence ())
332
335
return false ;
333
336
// FIXME: FMF is allowed on phi, but propagation is not handled correctly.
@@ -360,17 +363,18 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
360
363
361
364
// A reduction operation must only have one use of the reduction value.
362
365
if (!IsAPhi && !IsASelect && !isMinMaxRecurrenceKind (Kind) &&
366
+ !isSelectCmpRecurrenceKind (Kind) &&
363
367
hasMultipleUsesOf (Cur, VisitedInsts, 1 ))
364
368
return false ;
365
369
366
370
// All inputs to a PHI node must be a reduction value.
367
371
if (IsAPhi && Cur != Phi && !areAllUsesIn (Cur, VisitedInsts))
368
372
return false ;
369
373
370
- if (isIntMinMaxRecurrenceKind (Kind) &&
374
+ if (( isIntMinMaxRecurrenceKind (Kind) || Kind == RecurKind::SelectICmp ) &&
371
375
(isa<ICmpInst>(Cur) || isa<SelectInst>(Cur)))
372
376
++NumCmpSelectPatternInst;
373
- if (isFPMinMaxRecurrenceKind (Kind) &&
377
+ if (( isFPMinMaxRecurrenceKind (Kind) || Kind == RecurKind::SelectFCmp ) &&
374
378
(isa<FCmpInst>(Cur) || isa<SelectInst>(Cur)))
375
379
++NumCmpSelectPatternInst;
376
380
@@ -423,8 +427,9 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
423
427
((!isa<FCmpInst>(UI) && !isa<ICmpInst>(UI) &&
424
428
!isa<SelectInst>(UI)) ||
425
429
(!isConditionalRdxPattern (Kind, UI).isRecurrence () &&
426
- !isMinMaxPattern (UI, Kind, IgnoredVal)
427
- .isRecurrence ())))
430
+ !isSelectCmpPattern (TheLoop, Phi, UI, IgnoredVal)
431
+ .isRecurrence () &&
432
+ !isMinMaxPattern (UI, Kind, IgnoredVal).isRecurrence ())))
428
433
return false ;
429
434
430
435
// Remember that we completed the cycle.
@@ -442,6 +447,9 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
442
447
NumCmpSelectPatternInst != 0 )
443
448
return false ;
444
449
450
+ if (isSelectCmpRecurrenceKind (Kind) && NumCmpSelectPatternInst != 1 )
451
+ return false ;
452
+
445
453
if (!FoundStartPHI || !FoundReduxOp || !ExitInstruction)
446
454
return false ;
447
455
@@ -508,6 +516,63 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
508
516
return true ;
509
517
}
510
518
519
+ // We are looking for loops that do something like this:
520
+ // int r = 0;
521
+ // for (int i = 0; i < n; i++) {
522
+ // if (src[i] > 3)
523
+ // r = 3;
524
+ // }
525
+ // where the reduction value (r) only has two states, in this example 0 or 3.
526
+ // The generated LLVM IR for this type of loop will be like this:
527
+ // for.body:
528
+ // %r = phi i32 [ %spec.select, %for.body ], [ 0, %entry ]
529
+ // ...
530
+ // %cmp = icmp sgt i32 %5, 3
531
+ // %spec.select = select i1 %cmp, i32 3, i32 %r
532
+ // ...
533
+ // In general we can support vectorization of loops where 'r' flips between
534
+ // any two non-constants, provided they are loop invariant. The only thing
535
+ // we actually care about at the end of the loop is whether or not any lane
536
+ // in the selected vector is different from the start value. The final
537
+ // across-vector reduction after the loop simply involves choosing the start
538
+ // value if nothing changed (0 in the example above) or the other selected
539
+ // value (3 in the example above).
540
+ RecurrenceDescriptor::InstDesc
541
+ RecurrenceDescriptor::isSelectCmpPattern (Loop *Loop, PHINode *OrigPhi,
542
+ Instruction *I, InstDesc &Prev) {
543
+ // We must handle the select(cmp(),x,y) as a single instruction. Advance to
544
+ // the select.
545
+ CmpInst::Predicate Pred;
546
+ if (match (I, m_OneUse (m_Cmp (Pred, m_Value (), m_Value ())))) {
547
+ if (auto *Select = dyn_cast<SelectInst>(*I->user_begin ()))
548
+ return InstDesc (Select, Prev.getRecKind ());
549
+ }
550
+
551
+ // Only match select with single use cmp condition.
552
+ if (!match (I, m_Select (m_OneUse (m_Cmp (Pred, m_Value (), m_Value ())), m_Value (),
553
+ m_Value ())))
554
+ return InstDesc (false , I);
555
+
556
+ SelectInst *SI = cast<SelectInst>(I);
557
+ Value *NonPhi = nullptr ;
558
+
559
+ if (OrigPhi == dyn_cast<PHINode>(SI->getTrueValue ()))
560
+ NonPhi = SI->getFalseValue ();
561
+ else if (OrigPhi == dyn_cast<PHINode>(SI->getFalseValue ()))
562
+ NonPhi = SI->getTrueValue ();
563
+ else
564
+ return InstDesc (false , I);
565
+
566
+ // We are looking for selects of the form:
567
+ // select(cmp(), phi, loop_invariant) or
568
+ // select(cmp(), loop_invariant, phi)
569
+ if (!Loop->isLoopInvariant (NonPhi))
570
+ return InstDesc (false , I);
571
+
572
+ return InstDesc (I, isa<ICmpInst>(I->getOperand (0 )) ? RecurKind::SelectICmp
573
+ : RecurKind::SelectFCmp);
574
+ }
575
+
511
576
RecurrenceDescriptor::InstDesc
512
577
RecurrenceDescriptor::isMinMaxPattern (Instruction *I, RecurKind Kind,
513
578
const InstDesc &Prev) {
@@ -602,7 +667,8 @@ RecurrenceDescriptor::isConditionalRdxPattern(RecurKind Kind, Instruction *I) {
602
667
}
603
668
604
669
RecurrenceDescriptor::InstDesc
605
- RecurrenceDescriptor::isRecurrenceInstr (Instruction *I, RecurKind Kind,
670
+ RecurrenceDescriptor::isRecurrenceInstr (Loop *L, PHINode *OrigPhi,
671
+ Instruction *I, RecurKind Kind,
606
672
InstDesc &Prev, FastMathFlags FuncFMF) {
607
673
assert (Prev.getRecKind () == RecurKind::None || Prev.getRecKind () == Kind);
608
674
switch (I->getOpcode ()) {
@@ -636,6 +702,8 @@ RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurKind Kind,
636
702
case Instruction::FCmp:
637
703
case Instruction::ICmp:
638
704
case Instruction::Call:
705
+ if (isSelectCmpRecurrenceKind (Kind))
706
+ return isSelectCmpPattern (L, OrigPhi, I, Prev);
639
707
if (isIntMinMaxRecurrenceKind (Kind) ||
640
708
(((FuncFMF.noNaNs () && FuncFMF.noSignedZeros ()) ||
641
709
(isa<FPMathOperator>(I) && I->hasNoNaNs () &&
@@ -664,7 +732,6 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
664
732
RecurrenceDescriptor &RedDes,
665
733
DemandedBits *DB, AssumptionCache *AC,
666
734
DominatorTree *DT) {
667
-
668
735
BasicBlock *Header = TheLoop->getHeader ();
669
736
Function &F = *Header->getParent ();
670
737
FastMathFlags FMF;
@@ -709,6 +776,12 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
709
776
LLVM_DEBUG (dbgs () << " Found a UMIN reduction PHI." << *Phi << " \n " );
710
777
return true ;
711
778
}
779
+ if (AddReductionVar (Phi, RecurKind::SelectICmp, TheLoop, FMF, RedDes, DB, AC,
780
+ DT)) {
781
+ LLVM_DEBUG (dbgs () << " Found an integer conditional select reduction PHI."
782
+ << *Phi << " \n " );
783
+ return true ;
784
+ }
712
785
if (AddReductionVar (Phi, RecurKind::FMul, TheLoop, FMF, RedDes, DB, AC, DT)) {
713
786
LLVM_DEBUG (dbgs () << " Found an FMult reduction PHI." << *Phi << " \n " );
714
787
return true ;
@@ -725,6 +798,12 @@ bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop,
725
798
LLVM_DEBUG (dbgs () << " Found a float MIN reduction PHI." << *Phi << " \n " );
726
799
return true ;
727
800
}
801
+ if (AddReductionVar (Phi, RecurKind::SelectFCmp, TheLoop, FMF, RedDes, DB, AC,
802
+ DT)) {
803
+ LLVM_DEBUG (dbgs () << " Found a float conditional select reduction PHI."
804
+ << " PHI." << *Phi << " \n " );
805
+ return true ;
806
+ }
728
807
// Not a reduction of known type.
729
808
return false ;
730
809
}
@@ -831,8 +910,8 @@ bool RecurrenceDescriptor::isFirstOrderRecurrence(
831
910
832
911
// / This function returns the identity element (or neutral element) for
833
912
// / the operation K.
834
- Constant *RecurrenceDescriptor::getRecurrenceIdentity (RecurKind K, Type *Tp,
835
- FastMathFlags FMF) {
913
+ Value *RecurrenceDescriptor::getRecurrenceIdentity (RecurKind K, Type *Tp,
914
+ FastMathFlags FMF) {
836
915
switch (K) {
837
916
case RecurKind::Xor:
838
917
case RecurKind::Add:
@@ -872,6 +951,10 @@ Constant *RecurrenceDescriptor::getRecurrenceIdentity(RecurKind K, Type *Tp,
872
951
return ConstantFP::getInfinity (Tp, true );
873
952
case RecurKind::FMax:
874
953
return ConstantFP::getInfinity (Tp, false );
954
+ case RecurKind::SelectICmp:
955
+ case RecurKind::SelectFCmp:
956
+ return getRecurrenceStartValue ();
957
+ break ;
875
958
default :
876
959
llvm_unreachable (" Unknown recurrence kind" );
877
960
}
@@ -897,9 +980,11 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
897
980
case RecurKind::SMin:
898
981
case RecurKind::UMax:
899
982
case RecurKind::UMin:
983
+ case RecurKind::SelectICmp:
900
984
return Instruction::ICmp;
901
985
case RecurKind::FMax:
902
986
case RecurKind::FMin:
987
+ case RecurKind::SelectFCmp:
903
988
return Instruction::FCmp;
904
989
default :
905
990
llvm_unreachable (" Unknown recurrence operation" );
0 commit comments