Skip to content

Commit e1a16cd

Browse files
authored
[ExpandVectorPredication] Be more precise reporting changes (#102313)
This is used by PreISelIntrinsicLowering. With this change, PreISelIntrinsicLowering does not have to assume that there were changes just because we encountered a VP intrinsic.
1 parent f09a28e commit e1a16cd

File tree

3 files changed

+54
-26
lines changed

3 files changed

+54
-26
lines changed

llvm/include/llvm/CodeGen/ExpandVectorPredication.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,21 @@ namespace llvm {
1616
class TargetTransformInfo;
1717
class VPIntrinsic;
1818

19-
/// Expand a vector predication intrinsic. Returns true if the intrinsic was
20-
/// removed/replaced.
21-
bool expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
22-
const TargetTransformInfo &TTI);
19+
/// Represents the details the expansion of a VP intrinsic.
20+
enum class VPExpansionDetails {
21+
/// No change happened during expansion.
22+
IntrinsicUnchanged,
23+
/// At least one operand was updated.
24+
IntrinsicUpdated,
25+
/// The whole intrinsic was replaced.
26+
IntrinsicReplaced,
27+
};
28+
29+
/// Expand a vector predication intrinsic. Returns the kind of expansion
30+
/// that was applied to the intrinsic.
31+
VPExpansionDetails
32+
expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
33+
const TargetTransformInfo &TTI);
2334

2435
} // end namespace llvm
2536

llvm/lib/CodeGen/ExpandVectorPredication.cpp

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,15 @@ struct CachingVPExpander {
160160
Value *convertEVLToMask(IRBuilder<> &Builder, Value *EVLParam,
161161
ElementCount ElemCount);
162162

163-
Value *foldEVLIntoMask(VPIntrinsic &VPI);
163+
/// If needed, folds the EVL in the mask operand and discards the EVL
164+
/// parameter. Returns a pair of the value of the intrinsic after the change
165+
/// (if any) and whether the mask was actually folded.
166+
std::pair<Value *, bool> foldEVLIntoMask(VPIntrinsic &VPI);
164167

165168
/// "Remove" the %evl parameter of \p PI by setting it to the static vector
166-
/// length of the operation.
167-
void discardEVLParameter(VPIntrinsic &PI);
169+
/// length of the operation. Returns true if the %evl (if any) was effectively
170+
/// changed.
171+
bool discardEVLParameter(VPIntrinsic &PI);
168172

169173
/// Lower this VP binary operator to a unpredicated binary operator.
170174
Value *expandPredicationInBinaryOperator(IRBuilder<> &Builder,
@@ -206,7 +210,9 @@ struct CachingVPExpander {
206210
CachingVPExpander(const TargetTransformInfo &TTI)
207211
: TTI(TTI), UsingTTIOverrides(anyExpandVPOverridesSet()) {}
208212

209-
bool expandVectorPredication(VPIntrinsic &VPI);
213+
/// Expand llvm.vp.* intrinsics as requested by \p TTI.
214+
/// Returns the details of the expansion.
215+
VPExpansionDetails expandVectorPredication(VPIntrinsic &VPI);
210216
};
211217

212218
//// CachingVPExpander {
@@ -645,15 +651,15 @@ Value *CachingVPExpander::expandPredicationInComparison(IRBuilder<> &Builder,
645651
return NewCmp;
646652
}
647653

648-
void CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
654+
bool CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
649655
LLVM_DEBUG(dbgs() << "Discard EVL parameter in " << VPI << "\n");
650656

651657
if (VPI.canIgnoreVectorLengthParam())
652-
return;
658+
return false;
653659

654660
Value *EVLParam = VPI.getVectorLengthParam();
655661
if (!EVLParam)
656-
return;
662+
return false;
657663

658664
ElementCount StaticElemCount = VPI.getStaticVectorLength();
659665
Value *MaxEVL = nullptr;
@@ -672,16 +678,17 @@ void CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
672678
MaxEVL = ConstantInt::get(Int32Ty, StaticElemCount.getFixedValue(), false);
673679
}
674680
VPI.setVectorLengthParam(MaxEVL);
681+
return true;
675682
}
676683

677-
Value *CachingVPExpander::foldEVLIntoMask(VPIntrinsic &VPI) {
684+
std::pair<Value *, bool> CachingVPExpander::foldEVLIntoMask(VPIntrinsic &VPI) {
678685
LLVM_DEBUG(dbgs() << "Folding vlen for " << VPI << '\n');
679686

680687
IRBuilder<> Builder(&VPI);
681688

682689
// Ineffective %evl parameter and so nothing to do here.
683690
if (VPI.canIgnoreVectorLengthParam())
684-
return &VPI;
691+
return {&VPI, false};
685692

686693
// Only VP intrinsics can have an %evl parameter.
687694
Value *OldMaskParam = VPI.getMaskParam();
@@ -704,7 +711,7 @@ Value *CachingVPExpander::foldEVLIntoMask(VPIntrinsic &VPI) {
704711
"transformation did not render the evl param ineffective!");
705712

706713
// Reassess the modified instruction.
707-
return &VPI;
714+
return {&VPI, true};
708715
}
709716

710717
Value *CachingVPExpander::expandPredication(VPIntrinsic &VPI) {
@@ -807,21 +814,27 @@ CachingVPExpander::getVPLegalizationStrategy(const VPIntrinsic &VPI) const {
807814
return VPStrat;
808815
}
809816

810-
/// Expand llvm.vp.* intrinsics as requested by \p TTI.
811-
bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
817+
VPExpansionDetails
818+
CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
812819
auto Strategy = getVPLegalizationStrategy(VPI);
813820
sanitizeStrategy(VPI, Strategy);
814821

822+
VPExpansionDetails Changed = VPExpansionDetails::IntrinsicUnchanged;
823+
815824
// Transform the EVL parameter.
816825
switch (Strategy.EVLParamStrategy) {
817826
case VPLegalization::Legal:
818827
break;
819828
case VPLegalization::Discard:
820-
discardEVLParameter(VPI);
829+
if (discardEVLParameter(VPI))
830+
Changed = VPExpansionDetails::IntrinsicUpdated;
821831
break;
822832
case VPLegalization::Convert:
823-
if (foldEVLIntoMask(VPI))
833+
if (auto [NewVPI, Folded] = foldEVLIntoMask(VPI); Folded) {
834+
(void)NewVPI;
835+
Changed = VPExpansionDetails::IntrinsicUpdated;
824836
++NumFoldedVL;
837+
}
825838
break;
826839
}
827840

@@ -834,17 +847,17 @@ bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
834847
case VPLegalization::Convert:
835848
if (Value *V = expandPredication(VPI); V != &VPI) {
836849
++NumLoweredVPOps;
837-
// Return true if and only if the intrinsic was actually removed.
838-
return true;
850+
Changed = VPExpansionDetails::IntrinsicReplaced;
839851
}
840852
break;
841853
}
842854

843-
return false;
855+
return Changed;
844856
}
845857
} // namespace
846858

847-
bool llvm::expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
848-
const TargetTransformInfo &TTI) {
859+
VPExpansionDetails
860+
llvm::expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
861+
const TargetTransformInfo &TTI) {
849862
return CachingVPExpander(TTI).expandVectorPredication(VPI);
850863
}

llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,14 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
361361
Function *Parent = CI->getParent()->getParent();
362362
const TargetTransformInfo &TTI = LookupTTI(*Parent);
363363
auto *VPI = cast<VPIntrinsic>(CI);
364-
return expandVectorPredicationIntrinsic(*VPI, TTI);
364+
VPExpansionDetails ED = expandVectorPredicationIntrinsic(*VPI, TTI);
365+
// Expansion of VP intrinsics may change the IR but not actually
366+
// replace the intrinsic, so update Changed for the pass
367+
// and compute Removed for forEachCall.
368+
Changed |= ED != VPExpansionDetails::IntrinsicUnchanged;
369+
bool Removed = ED == VPExpansionDetails::IntrinsicReplaced;
370+
return Removed;
365371
});
366-
// Not all intrinsics are removed, but the code is changed in any case.
367-
Changed = true;
368372
break;
369373
case Intrinsic::objc_autorelease:
370374
Changed |= lowerObjCCall(F, "objc_autorelease");

0 commit comments

Comments
 (0)