Skip to content

Commit c890582

Browse files
committed
[VPlan] Account for live-in entries in MinBW used by replicate recipes.
In some cases MinBWs may contain entries for live-ins that are not used by VPWidenRecipe or VPWidenSelectRecipes. In those cases, the live-ins won't get processed, so make sure we include them in the count when used as operands in VPWidenCast and VPWidenSelectRecipe. Fixes #74231
1 parent 2a3f119 commit c890582

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,8 +905,32 @@ void VPlanTransforms::truncateToMinimalBitwidths(
905905
// type. Skip those here, after incrementing NumProcessedRecipes. Also
906906
// skip casts which do not need to be handled explicitly here, as
907907
// redundant casts will be removed during recipe simplification.
908-
if (isa<VPReplicateRecipe, VPWidenCastRecipe>(&R))
908+
if (isa<VPReplicateRecipe, VPWidenCastRecipe>(&R)) {
909+
#ifndef NDEBUG
910+
// If any of the operands is a live-in and not used by VPWidenRecipe or
911+
// VPWidenSelectRecipe, but in MinBWs, make sure it is counted as
912+
// processed as well. When MinBWs is currently constructed, there is no
913+
// information about whether recipes are widened or replicated and in
914+
// case they are reciplicated the operands are not truncated. Counting
915+
// them them here ensures we do not miss any recipes in MinBWs.
916+
// TODO: Remove once the analysis is done on VPlan.
917+
for (VPValue *Op : R.operands()) {
918+
if (!Op->isLiveIn())
919+
continue;
920+
auto *UV = dyn_cast_or_null<Instruction>(Op->getUnderlyingValue());
921+
if (UV && MinBWs.contains(UV) && !ProcessedTruncs.contains(Op) &&
922+
all_of(Op->users(), [](VPUser *U) {
923+
return !isa<VPWidenRecipe, VPWidenSelectRecipe>(U);
924+
})) {
925+
// Add an entry to ProcessedTruncs to avoid counting the same
926+
// operand multiple times.
927+
ProcessedTruncs[Op] = nullptr;
928+
NumProcessedRecipes += 1;
929+
}
930+
}
931+
#endif
909932
continue;
933+
}
910934

911935
Type *OldResTy = TypeInfo.inferScalarType(ResultVPV);
912936
unsigned OldResSizeInBits = OldResTy->getScalarSizeInBits();

llvm/test/Transforms/LoopVectorize/AArch64/deterministic-type-shrinkage.ll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,37 @@ loop:
383383
exit:
384384
ret void
385385
}
386+
387+
; Test case for #74231.
388+
define void @replicate_operands_in_with_operands_in_minbws(ptr %dst, ptr noalias %src.1, ptr noalias %src.2, i32 %x) {
389+
entry:
390+
%sub = sub i32 %x, 10
391+
br label %loop.header
392+
393+
loop.header:
394+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
395+
%gep.src.1 = getelementptr inbounds i32, ptr %src.1, i64 %iv
396+
%l = load i32, ptr %gep.src.1
397+
%c.1 = icmp eq i32 %l, 10
398+
br i1 %c.1, label %loop.latch, label %if.then
399+
400+
if.then:
401+
%gep.src.2 = getelementptr inbounds i16, ptr %src.2, i64 %iv
402+
%l.2 = load i16, ptr %gep.src.2
403+
%c.2 = icmp ule i16 %l.2, 99
404+
%conv = zext i16 %l.2 to i32
405+
%sel = select i1 %c.2, i32 %sub, i32 %conv
406+
%add = add i32 %conv, %sel
407+
%trunc = trunc i32 %add to i16
408+
%gep.dst = getelementptr inbounds i32, ptr %dst, i64 %iv
409+
store i16 %trunc, ptr %gep.dst, align 2
410+
br label %loop.latch
411+
412+
loop.latch:
413+
%iv.next = add i64 %iv, 1
414+
%tobool.not = icmp eq i64 %iv.next, 1000
415+
br i1 %tobool.not, label %exit, label %loop.header
416+
417+
exit:
418+
ret void
419+
}

0 commit comments

Comments
 (0)