Skip to content

Commit 3176f25

Browse files
authored
[IA][AArch64]: Construct (de)interleave4 out of (de)interleave2 (#89276)
- [AArch64]: TargetLowering is updated to spot load/store (de)interleave4 like sequences using PatternMatch, and emit equivalent sve.ld4 and sve.st4 intrinsics.
1 parent 7c4c72b commit 3176f25

File tree

12 files changed

+961
-384
lines changed

12 files changed

+961
-384
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3156,8 +3156,11 @@ class TargetLoweringBase {
31563156
///
31573157
/// \p DI is the deinterleave intrinsic.
31583158
/// \p LI is the accompanying load instruction
3159-
virtual bool lowerDeinterleaveIntrinsicToLoad(IntrinsicInst *DI,
3160-
LoadInst *LI) const {
3159+
/// \p DeadInsts is a reference to a vector that keeps track of dead
3160+
/// instruction during transformations.
3161+
virtual bool lowerDeinterleaveIntrinsicToLoad(
3162+
IntrinsicInst *DI, LoadInst *LI,
3163+
SmallVectorImpl<Instruction *> &DeadInsts) const {
31613164
return false;
31623165
}
31633166

@@ -3167,8 +3170,11 @@ class TargetLoweringBase {
31673170
///
31683171
/// \p II is the interleave intrinsic.
31693172
/// \p SI is the accompanying store instruction
3170-
virtual bool lowerInterleaveIntrinsicToStore(IntrinsicInst *II,
3171-
StoreInst *SI) const {
3173+
/// \p DeadInsts is a reference to a vector that keeps track of dead
3174+
/// instruction during transformations.
3175+
virtual bool lowerInterleaveIntrinsicToStore(
3176+
IntrinsicInst *II, StoreInst *SI,
3177+
SmallVectorImpl<Instruction *> &DeadInsts) const {
31723178
return false;
31733179
}
31743180

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2940,6 +2940,17 @@ inline VScaleVal_match m_VScale() {
29402940
return VScaleVal_match();
29412941
}
29422942

2943+
template <typename Opnd0, typename Opnd1>
2944+
inline typename m_Intrinsic_Ty<Opnd0, Opnd1>::Ty
2945+
m_Interleave2(const Opnd0 &Op0, const Opnd1 &Op1) {
2946+
return m_Intrinsic<Intrinsic::vector_interleave2>(Op0, Op1);
2947+
}
2948+
2949+
template <typename Opnd>
2950+
inline typename m_Intrinsic_Ty<Opnd>::Ty m_Deinterleave2(const Opnd &Op) {
2951+
return m_Intrinsic<Intrinsic::vector_deinterleave2>(Op);
2952+
}
2953+
29432954
template <typename LHS, typename RHS, unsigned Opcode, bool Commutable = false>
29442955
struct LogicalOp_match {
29452956
LHS L;

llvm/lib/CodeGen/InterleavedAccessPass.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ bool InterleavedAccessImpl::lowerDeinterleaveIntrinsic(
489489
LLVM_DEBUG(dbgs() << "IA: Found a deinterleave intrinsic: " << *DI << "\n");
490490

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

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

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

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

517518
// We now have a target-specific store, so delete the old one.
518519
DeadInsts.push_back(SI);
519520
DeadInsts.push_back(II);
521+
DeadInsts.insert(DeadInsts.end(), InterleaveDeadInsts.begin(),
522+
InterleaveDeadInsts.end());
520523
return true;
521524
}
522525

@@ -537,7 +540,7 @@ bool InterleavedAccessImpl::runOnFunction(Function &F) {
537540
// with a factor of 2.
538541
if (II->getIntrinsicID() == Intrinsic::vector_deinterleave2)
539542
Changed |= lowerDeinterleaveIntrinsic(II, DeadInsts);
540-
if (II->getIntrinsicID() == Intrinsic::vector_interleave2)
543+
else if (II->getIntrinsicID() == Intrinsic::vector_interleave2)
541544
Changed |= lowerInterleaveIntrinsic(II, DeadInsts);
542545
}
543546
}

0 commit comments

Comments
 (0)