Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IA]: Construct (de)interleave4 out of (de)interleave2 #89276

Merged
merged 12 commits into from
Aug 12, 2024
Merged
14 changes: 10 additions & 4 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -3155,8 +3155,11 @@ class TargetLoweringBase {
///
/// \p DI is the deinterleave intrinsic.
/// \p LI is the accompanying load instruction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments on these 2 functions look outdated. It would be nice to explain what DeadInsts should look like going into and out of the function given it's a reference to a vector.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

virtual bool lowerDeinterleaveIntrinsicToLoad(IntrinsicInst *DI,
LoadInst *LI) const {
/// \p DeadInsts is a reference to a vector that keeps track of dead
/// instruction during transformations.
virtual bool lowerDeinterleaveIntrinsicToLoad(
IntrinsicInst *DI, LoadInst *LI,
SmallVectorImpl<Instruction *> &DeadInsts) const {
return false;
}

Expand All @@ -3166,8 +3169,11 @@ class TargetLoweringBase {
///
/// \p II is the interleave intrinsic.
/// \p SI is the accompanying store instruction
virtual bool lowerInterleaveIntrinsicToStore(IntrinsicInst *II,
StoreInst *SI) const {
/// \p DeadInsts is a reference to a vector that keeps track of dead
/// instruction during transformations.
virtual bool lowerInterleaveIntrinsicToStore(
IntrinsicInst *II, StoreInst *SI,
SmallVectorImpl<Instruction *> &DeadInsts) const {
return false;
}

Expand Down
11 changes: 11 additions & 0 deletions llvm/include/llvm/IR/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -2924,6 +2924,17 @@ inline VScaleVal_match m_VScale() {
return VScaleVal_match();
}

template <typename Opnd0, typename Opnd1>
inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty
m_Interleave2(const Opnd0 &Op0, const Opnd1 &Op1) {
return m_Intrinsic<Intrinsic::vector_interleave2>(Op0, Op1);
}

template <typename Opnd>
inline typename m_Intrinsic_Ty<Opnd>::Ty m_Deinterleave2(const Opnd &Op) {
return m_Intrinsic<Intrinsic::vector_deinterleave2>(Op);
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @paulwalker-arm
I have added pattern matchers as you advised. Is this what you mean ?
I have tested that implementation locally, but I don't want to update the other files until we agree on the approach.

Copy link
Collaborator

@paulwalker-arm paulwalker-arm Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite. PatternMatch should not care about how the IR is used, that's up to the user of the interface. It exists purely to provide a convenient way to express the tree of IR to compare against. Interleave2_match does this but Deinterleave2_match is trying to encode logic for your specific use case, which belongs with the transformation itself (NOTE: m_ExtractValue exists so presumably you'll want to use that when constructing your match call).

FYI: m_Interleave2 can be simplified, see m_VecReverse.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated it

template <typename LHS, typename RHS, unsigned Opcode, bool Commutable = false>
struct LogicalOp_match {
LHS L;
Expand Down
9 changes: 6 additions & 3 deletions llvm/lib/CodeGen/InterleavedAccessPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ bool InterleavedAccessImpl::lowerDeinterleaveIntrinsic(
LLVM_DEBUG(dbgs() << "IA: Found a deinterleave intrinsic: " << *DI << "\n");

// Try and match this with target specific intrinsics.
if (!TLI->lowerDeinterleaveIntrinsicToLoad(DI, LI))
if (!TLI->lowerDeinterleaveIntrinsicToLoad(DI, LI, DeadInsts))
return false;

// We now have a target-specific load, so delete the old one.
Expand All @@ -510,13 +510,16 @@ bool InterleavedAccessImpl::lowerInterleaveIntrinsic(

LLVM_DEBUG(dbgs() << "IA: Found an interleave intrinsic: " << *II << "\n");

SmallVector<Instruction *, 4> InterleaveDeadInsts;
// Try and match this with target specific intrinsics.
if (!TLI->lowerInterleaveIntrinsicToStore(II, SI))
if (!TLI->lowerInterleaveIntrinsicToStore(II, SI, InterleaveDeadInsts))
return false;

// We now have a target-specific store, so delete the old one.
DeadInsts.push_back(SI);
DeadInsts.push_back(II);
DeadInsts.insert(DeadInsts.end(), InterleaveDeadInsts.begin(),
InterleaveDeadInsts.end());
return true;
}

Expand All @@ -537,7 +540,7 @@ bool InterleavedAccessImpl::runOnFunction(Function &F) {
// with a factor of 2.
if (II->getIntrinsicID() == Intrinsic::vector_deinterleave2)
Changed |= lowerDeinterleaveIntrinsic(II, DeadInsts);
if (II->getIntrinsicID() == Intrinsic::vector_interleave2)
else if (II->getIntrinsicID() == Intrinsic::vector_interleave2)
Changed |= lowerInterleaveIntrinsic(II, DeadInsts);
}
}
Expand Down
Loading
Loading