@@ -161,27 +161,39 @@ static std::pair<Type *, bool> computeRecurrenceType(Instruction *Exit,
161
161
162
162
// / Collect cast instructions that can be ignored in the vectorizer's cost
163
163
// / model, given a reduction exit value and the minimal type in which the
164
- // / reduction can be represented.
165
- static void collectCastsToIgnore (Loop *TheLoop, Instruction *Exit,
166
- Type *RecurrenceType,
167
- SmallPtrSetImpl<Instruction *> &Casts) {
164
+ // reduction can be represented. Also search casts to the recurrence type
165
+ // to find the minimum width used by the recurrence.
166
+ static void collectCastInstrs (Loop *TheLoop, Instruction *Exit,
167
+ Type *RecurrenceType,
168
+ SmallPtrSetImpl<Instruction *> &Casts,
169
+ unsigned &MinWidthCastToRecurTy) {
168
170
169
171
SmallVector<Instruction *, 8 > Worklist;
170
172
SmallPtrSet<Instruction *, 8 > Visited;
171
173
Worklist.push_back (Exit);
174
+ MinWidthCastToRecurTy = -1U ;
172
175
173
176
while (!Worklist.empty ()) {
174
177
Instruction *Val = Worklist.pop_back_val ();
175
178
Visited.insert (Val);
176
- if (auto *Cast = dyn_cast<CastInst>(Val))
179
+ if (auto *Cast = dyn_cast<CastInst>(Val)) {
177
180
if (Cast->getSrcTy () == RecurrenceType) {
178
181
// If the source type of a cast instruction is equal to the recurrence
179
182
// type, it will be eliminated, and should be ignored in the vectorizer
180
183
// cost model.
181
184
Casts.insert (Cast);
182
185
continue ;
183
186
}
184
-
187
+ if (Cast->getDestTy () == RecurrenceType) {
188
+ // The minimum width used by the recurrence is found by checking for
189
+ // casts on its operands. The minimum width is used by the vectorizer
190
+ // when finding the widest type for in-loop reductions without any
191
+ // loads/stores.
192
+ MinWidthCastToRecurTy = std::min<unsigned >(
193
+ MinWidthCastToRecurTy, Cast->getSrcTy ()->getScalarSizeInBits ());
194
+ continue ;
195
+ }
196
+ }
185
197
// Add all operands to the work list if they are loop-varying values that
186
198
// we haven't yet visited.
187
199
for (Value *O : cast<User>(Val)->operands ())
@@ -265,6 +277,7 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
265
277
// Data used for determining if the recurrence has been type-promoted.
266
278
Type *RecurrenceType = Phi->getType ();
267
279
SmallPtrSet<Instruction *, 4 > CastInsts;
280
+ unsigned MinWidthCastToRecurrenceType;
268
281
Instruction *Start = Phi;
269
282
bool IsSigned = false ;
270
283
@@ -500,21 +513,24 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
500
513
computeRecurrenceType (ExitInstruction, DB, AC, DT);
501
514
if (ComputedType != RecurrenceType)
502
515
return false ;
503
-
504
- // The recurrence expression will be represented in a narrower type. If
505
- // there are any cast instructions that will be unnecessary, collect them
506
- // in CastInsts. Note that the 'and' instruction was already included in
507
- // this list.
508
- //
509
- // TODO: A better way to represent this may be to tag in some way all the
510
- // instructions that are a part of the reduction. The vectorizer cost
511
- // model could then apply the recurrence type to these instructions,
512
- // without needing a white list of instructions to ignore.
513
- // This may also be useful for the inloop reductions, if it can be
514
- // kept simple enough.
515
- collectCastsToIgnore (TheLoop, ExitInstruction, RecurrenceType, CastInsts);
516
516
}
517
517
518
+ // Collect cast instructions and the minimum width used by the recurrence.
519
+ // If the starting value is not the same as the phi node and the computed
520
+ // recurrence type is equal to the recurrence type, the recurrence expression
521
+ // will be represented in a narrower or wider type. If there are any cast
522
+ // instructions that will be unnecessary, collect them in CastsFromRecurTy.
523
+ // Note that the 'and' instruction was already included in this list.
524
+ //
525
+ // TODO: A better way to represent this may be to tag in some way all the
526
+ // instructions that are a part of the reduction. The vectorizer cost
527
+ // model could then apply the recurrence type to these instructions,
528
+ // without needing a white list of instructions to ignore.
529
+ // This may also be useful for the inloop reductions, if it can be
530
+ // kept simple enough.
531
+ collectCastInstrs (TheLoop, ExitInstruction, RecurrenceType, CastInsts,
532
+ MinWidthCastToRecurrenceType);
533
+
518
534
// We found a reduction var if we have reached the original phi node and we
519
535
// only have a single instruction with out-of-loop users.
520
536
@@ -524,7 +540,8 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,
524
540
// Save the description of this reduction variable.
525
541
RecurrenceDescriptor RD (RdxStart, ExitInstruction, Kind, FMF,
526
542
ReduxDesc.getExactFPMathInst (), RecurrenceType,
527
- IsSigned, IsOrdered, CastInsts);
543
+ IsSigned, IsOrdered, CastInsts,
544
+ MinWidthCastToRecurrenceType);
528
545
RedDes = RD;
529
546
530
547
return true ;
0 commit comments