Skip to content

Commit b9adc4a

Browse files
authored
[IA] Use a single callback for lowerInterleaveIntrinsic [nfc] (#148978) (#149168)
This continues in the direction started by commit 4b81dc7. We essentially merges the handling for VPStore - currently in lowerInterleavedVPStore which is shared between shuffle and intrinsic based interleaves - into the existing dedicated routine.
1 parent b413982 commit b9adc4a

File tree

6 files changed

+70
-38
lines changed

6 files changed

+70
-38
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,10 +3261,14 @@ class LLVM_ABI TargetLoweringBase {
32613261
/// Return true on success. Currently only supports
32623262
/// llvm.vector.interleave{2,3,5,7}
32633263
///
3264-
/// \p SI is the accompanying store instruction
3264+
/// \p Store is the accompanying store instruction. Can be either a plain
3265+
/// store or a vp.store intrinsic.
3266+
/// \p Mask is a per-segment (i.e. number of lanes equal to that of one
3267+
/// component being interwoven) mask. Can be nullptr, in which case the
3268+
/// result is uncondiitional.
32653269
/// \p InterleaveValues contains the interleaved values.
32663270
virtual bool
3267-
lowerInterleaveIntrinsicToStore(StoreInst *SI,
3271+
lowerInterleaveIntrinsicToStore(Instruction *Store, Value *Mask,
32683272
ArrayRef<Value *> InterleaveValues) const {
32693273
return false;
32703274
}

llvm/lib/CodeGen/InterleavedAccessPass.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -662,36 +662,33 @@ bool InterleavedAccessImpl::lowerInterleaveIntrinsic(
662662
const unsigned Factor = getInterleaveIntrinsicFactor(II->getIntrinsicID());
663663
assert(Factor && "unexpected interleave intrinsic");
664664

665+
Value *Mask = nullptr;
665666
if (auto *VPStore = dyn_cast<VPIntrinsic>(StoredBy)) {
666667
if (VPStore->getIntrinsicID() != Intrinsic::vp_store)
667668
return false;
668669

669670
Value *WideMask = VPStore->getOperand(2);
670-
Value *Mask = getMask(WideMask, Factor,
671-
cast<VectorType>(InterleaveValues[0]->getType()));
671+
Mask = getMask(WideMask, Factor,
672+
cast<VectorType>(InterleaveValues[0]->getType()));
672673
if (!Mask)
673674
return false;
674675

675676
LLVM_DEBUG(dbgs() << "IA: Found a vp.store with interleave intrinsic "
676677
<< *II << " and factor = " << Factor << "\n");
677-
678-
// Since lowerInterleavedStore expects Shuffle and StoreInst, use special
679-
// TLI function to emit target-specific interleaved instruction.
680-
if (!TLI->lowerInterleavedVPStore(VPStore, Mask, InterleaveValues))
681-
return false;
682678
} else {
683679
auto *SI = cast<StoreInst>(StoredBy);
684680
if (!SI->isSimple())
685681
return false;
686682

687683
LLVM_DEBUG(dbgs() << "IA: Found a store with interleave intrinsic " << *II
688684
<< " and factor = " << Factor << "\n");
689-
690-
// Try and match this with target specific intrinsics.
691-
if (!TLI->lowerInterleaveIntrinsicToStore(SI, InterleaveValues))
692-
return false;
693685
}
694686

687+
// Try and match this with target specific intrinsics.
688+
if (!TLI->lowerInterleaveIntrinsicToStore(cast<Instruction>(StoredBy), Mask,
689+
InterleaveValues))
690+
return false;
691+
695692
// We now have a target-specific store, so delete the old one.
696693
DeadInsts.insert(cast<Instruction>(StoredBy));
697694
DeadInsts.insert(II);

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17564,12 +17564,17 @@ bool AArch64TargetLowering::lowerDeinterleaveIntrinsicToLoad(
1756417564
}
1756517565

1756617566
bool AArch64TargetLowering::lowerInterleaveIntrinsicToStore(
17567-
StoreInst *SI, ArrayRef<Value *> InterleavedValues) const {
17567+
Instruction *Store, Value *Mask,
17568+
ArrayRef<Value *> InterleavedValues) const {
1756817569
unsigned Factor = InterleavedValues.size();
1756917570
if (Factor != 2 && Factor != 4) {
1757017571
LLVM_DEBUG(dbgs() << "Matching st2 and st4 patterns failed\n");
1757117572
return false;
1757217573
}
17574+
StoreInst *SI = dyn_cast<StoreInst>(Store);
17575+
if (!SI)
17576+
return false;
17577+
assert(!Mask && "Unexpected mask on plain store");
1757317578

1757417579
VectorType *VTy = cast<VectorType>(InterleavedValues[0]->getType());
1757517580
const DataLayout &DL = SI->getModule()->getDataLayout();

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ class AArch64TargetLowering : public TargetLowering {
222222
IntrinsicInst *DI) const override;
223223

224224
bool lowerInterleaveIntrinsicToStore(
225-
StoreInst *SI, ArrayRef<Value *> InterleaveValues) const override;
225+
Instruction *Store, Value *Mask,
226+
ArrayRef<Value *> InterleaveValues) const override;
226227

227228
bool isLegalAddImmediate(int64_t) const override;
228229
bool isLegalAddScalableImmediate(int64_t) const override;

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,8 @@ class RISCVTargetLowering : public TargetLowering {
441441
IntrinsicInst *DI) const override;
442442

443443
bool lowerInterleaveIntrinsicToStore(
444-
StoreInst *SI, ArrayRef<Value *> InterleaveValues) const override;
444+
Instruction *Store, Value *Mask,
445+
ArrayRef<Value *> InterleaveValues) const override;
445446

446447
bool lowerInterleavedVPLoad(VPIntrinsic *Load, Value *Mask,
447448
ArrayRef<Value *> DeinterleaveRes) const override;

llvm/lib/Target/RISCV/RISCVInterleavedAccess.cpp

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -349,58 +349,82 @@ bool RISCVTargetLowering::lowerDeinterleaveIntrinsicToLoad(
349349
}
350350

351351
bool RISCVTargetLowering::lowerInterleaveIntrinsicToStore(
352-
StoreInst *SI, ArrayRef<Value *> InterleaveValues) const {
352+
Instruction *Store, Value *Mask, ArrayRef<Value *> InterleaveValues) const {
353353
unsigned Factor = InterleaveValues.size();
354354
if (Factor > 8)
355355
return false;
356356

357-
assert(SI->isSimple());
358-
IRBuilder<> Builder(SI);
357+
IRBuilder<> Builder(Store);
359358

360359
auto *InVTy = cast<VectorType>(InterleaveValues[0]->getType());
361-
auto *PtrTy = SI->getPointerOperandType();
362-
const DataLayout &DL = SI->getDataLayout();
360+
const DataLayout &DL = Store->getDataLayout();
361+
Type *XLenTy = Type::getIntNTy(Store->getContext(), Subtarget.getXLen());
363362

364-
if (!isLegalInterleavedAccessType(InVTy, Factor, SI->getAlign(),
365-
SI->getPointerAddressSpace(), DL))
366-
return false;
363+
Value *Ptr, *VL;
364+
Align Alignment;
365+
if (auto *SI = dyn_cast<StoreInst>(Store)) {
366+
assert(SI->isSimple());
367+
Ptr = SI->getPointerOperand();
368+
Alignment = SI->getAlign();
369+
assert(!Mask && "Unexpected mask on a store");
370+
Mask = Builder.getAllOnesMask(InVTy->getElementCount());
371+
VL = isa<FixedVectorType>(InVTy)
372+
? Builder.CreateElementCount(XLenTy, InVTy->getElementCount())
373+
: Constant::getAllOnesValue(XLenTy);
374+
} else {
375+
auto *VPStore = cast<VPIntrinsic>(Store);
376+
assert(VPStore->getIntrinsicID() == Intrinsic::vp_store &&
377+
"Unexpected intrinsic");
378+
Ptr = VPStore->getMemoryPointerParam();
379+
Alignment = VPStore->getPointerAlignment().value_or(
380+
DL.getABITypeAlign(InVTy->getElementType()));
381+
382+
assert(Mask && "vp.store needs a mask!");
383+
384+
Value *WideEVL = VPStore->getVectorLengthParam();
385+
// Conservatively check if EVL is a multiple of factor, otherwise some
386+
// (trailing) elements might be lost after the transformation.
387+
if (!isMultipleOfN(WideEVL, DL, Factor))
388+
return false;
367389

368-
Type *XLenTy = Type::getIntNTy(SI->getContext(), Subtarget.getXLen());
390+
VL = Builder.CreateZExt(
391+
Builder.CreateUDiv(WideEVL,
392+
ConstantInt::get(WideEVL->getType(), Factor)),
393+
XLenTy);
394+
}
395+
Type *PtrTy = Ptr->getType();
396+
unsigned AS = Ptr->getType()->getPointerAddressSpace();
397+
if (!isLegalInterleavedAccessType(InVTy, Factor, Alignment, AS, DL))
398+
return false;
369399

370400
if (isa<FixedVectorType>(InVTy)) {
371401
Function *VssegNFunc = Intrinsic::getOrInsertDeclaration(
372-
SI->getModule(), FixedVssegIntrIds[Factor - 2], {InVTy, PtrTy, XLenTy});
373-
402+
Store->getModule(), FixedVssegIntrIds[Factor - 2],
403+
{InVTy, PtrTy, XLenTy});
374404
SmallVector<Value *, 10> Ops(InterleaveValues);
375-
Value *VL = Builder.CreateElementCount(XLenTy, InVTy->getElementCount());
376-
Value *Mask = Builder.getAllOnesMask(InVTy->getElementCount());
377-
Ops.append({SI->getPointerOperand(), Mask, VL});
378-
405+
Ops.append({Ptr, Mask, VL});
379406
Builder.CreateCall(VssegNFunc, Ops);
380407
return true;
381408
}
382409
unsigned SEW = DL.getTypeSizeInBits(InVTy->getElementType());
383410
unsigned NumElts = InVTy->getElementCount().getKnownMinValue();
384411
Type *VecTupTy = TargetExtType::get(
385-
SI->getContext(), "riscv.vector.tuple",
386-
ScalableVectorType::get(Type::getInt8Ty(SI->getContext()),
412+
Store->getContext(), "riscv.vector.tuple",
413+
ScalableVectorType::get(Type::getInt8Ty(Store->getContext()),
387414
NumElts * SEW / 8),
388415
Factor);
389416

390-
Value *VL = Constant::getAllOnesValue(XLenTy);
391-
Value *Mask = Builder.getAllOnesMask(InVTy->getElementCount());
392-
393417
Value *StoredVal = PoisonValue::get(VecTupTy);
394418
for (unsigned i = 0; i < Factor; ++i)
395419
StoredVal = Builder.CreateIntrinsic(
396420
Intrinsic::riscv_tuple_insert, {VecTupTy, InVTy},
397421
{StoredVal, InterleaveValues[i], Builder.getInt32(i)});
398422

399423
Function *VssegNFunc = Intrinsic::getOrInsertDeclaration(
400-
SI->getModule(), ScalableVssegIntrIds[Factor - 2],
424+
Store->getModule(), ScalableVssegIntrIds[Factor - 2],
401425
{VecTupTy, PtrTy, Mask->getType(), VL->getType()});
402426

403-
Value *Operands[] = {StoredVal, SI->getPointerOperand(), Mask, VL,
427+
Value *Operands[] = {StoredVal, Ptr, Mask, VL,
404428
ConstantInt::get(XLenTy, Log2_64(SEW))};
405429
Builder.CreateCall(VssegNFunc, Operands);
406430
return true;

0 commit comments

Comments
 (0)