Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 55 additions & 82 deletions llvm/lib/Target/RISCV/RISCVInterleavedAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,52 @@ static bool isMultipleOfN(const Value *V, const DataLayout &DL, unsigned N) {
return false;
}

static bool getMemOperands(IRBuilderBase &Builder, unsigned Factor,
VectorType *VTy, const DataLayout &DL, Type *XLenTy,
Instruction *I, Value *&Ptr, Value *&Mask,
Value *&VL, Align &Alignment) {
ElementCount EC = VTy->getElementCount();
if (auto *LI = dyn_cast<LoadInst>(I)) {
assert(LI->isSimple());
Ptr = LI->getPointerOperand();
Alignment = LI->getAlign();
assert(!Mask && "Unexpected mask on a load\n");
Mask = Builder.getAllOnesMask(EC);
VL = isa<FixedVectorType>(VTy) ? Builder.CreateElementCount(XLenTy, EC)
: Constant::getAllOnesValue(XLenTy);
return true;
}
if (auto *SI = dyn_cast<StoreInst>(I)) {
assert(SI->isSimple());
Ptr = SI->getPointerOperand();
Alignment = SI->getAlign();
assert(!Mask && "Unexpected mask on a store");
Mask = Builder.getAllOnesMask(EC);
VL = isa<FixedVectorType>(VTy) ? Builder.CreateElementCount(XLenTy, EC)
: Constant::getAllOnesValue(XLenTy);
return true;
}
auto *VPLdSt = cast<VPIntrinsic>(I);
assert((VPLdSt->getIntrinsicID() == Intrinsic::vp_load ||
VPLdSt->getIntrinsicID() == Intrinsic::vp_store) &&
"Unexpected intrinsic");
Ptr = VPLdSt->getMemoryPointerParam();
Alignment = VPLdSt->getPointerAlignment().value_or(
DL.getABITypeAlign(VTy->getElementType()));

assert(Mask && "vp.load needs a mask!");

Value *WideEVL = VPLdSt->getVectorLengthParam();
// Conservatively check if EVL is a multiple of factor, otherwise some
// (trailing) elements might be lost after the transformation.
if (!isMultipleOfN(WideEVL, I->getDataLayout(), Factor))
return false;

auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
VL = Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
return true;
}

/// Lower an interleaved load into a vlsegN intrinsic.
///
/// E.g. Lower an interleaved load (Factor = 2):
Expand All @@ -127,32 +173,9 @@ bool RISCVTargetLowering::lowerInterleavedLoad(

Value *Ptr, *VL;
Align Alignment;
if (auto *LI = dyn_cast<LoadInst>(Load)) {
assert(LI->isSimple());
Ptr = LI->getPointerOperand();
Alignment = LI->getAlign();
assert(!Mask && "Unexpected mask on a load\n");
Mask = Builder.getAllOnesMask(VTy->getElementCount());
VL = Builder.CreateElementCount(XLenTy, VTy->getElementCount());
} else {
auto *VPLoad = cast<VPIntrinsic>(Load);
assert(VPLoad->getIntrinsicID() == Intrinsic::vp_load &&
"Unexpected intrinsic");
Ptr = VPLoad->getMemoryPointerParam();
Alignment = VPLoad->getPointerAlignment().value_or(
DL.getABITypeAlign(VTy->getElementType()));

assert(Mask && "vp.load needs a mask!");

Value *WideEVL = VPLoad->getVectorLengthParam();
// Conservatively check if EVL is a multiple of factor, otherwise some
// (trailing) elements might be lost after the transformation.
if (!isMultipleOfN(WideEVL, DL, Factor))
return false;

auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
VL = Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
}
if (!getMemOperands(Builder, Factor, VTy, DL, XLenTy, Load, Ptr, Mask, VL,
Alignment))
return false;

Type *PtrTy = Ptr->getType();
unsigned AS = PtrTy->getPointerAddressSpace();
Expand Down Expand Up @@ -296,34 +319,9 @@ bool RISCVTargetLowering::lowerDeinterleaveIntrinsicToLoad(

Value *Ptr, *VL;
Align Alignment;
if (auto *LI = dyn_cast<LoadInst>(Load)) {
assert(LI->isSimple());
Ptr = LI->getPointerOperand();
Alignment = LI->getAlign();
assert(!Mask && "Unexpected mask on a load\n");
Mask = Builder.getAllOnesMask(ResVTy->getElementCount());
VL = isa<FixedVectorType>(ResVTy)
? Builder.CreateElementCount(XLenTy, ResVTy->getElementCount())
: Constant::getAllOnesValue(XLenTy);
} else {
auto *VPLoad = cast<VPIntrinsic>(Load);
assert(VPLoad->getIntrinsicID() == Intrinsic::vp_load &&
"Unexpected intrinsic");
Ptr = VPLoad->getMemoryPointerParam();
Alignment = VPLoad->getPointerAlignment().value_or(
DL.getABITypeAlign(ResVTy->getElementType()));

assert(Mask && "vp.load needs a mask!");

Value *WideEVL = VPLoad->getVectorLengthParam();
// Conservatively check if EVL is a multiple of factor, otherwise some
// (trailing) elements might be lost after the transformation.
if (!isMultipleOfN(WideEVL, Load->getDataLayout(), Factor))
return false;

auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
VL = Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
}
if (!getMemOperands(Builder, Factor, ResVTy, DL, XLenTy, Load, Ptr, Mask, VL,
Alignment))
return false;

Type *PtrTy = Ptr->getType();
unsigned AS = PtrTy->getPointerAddressSpace();
Expand Down Expand Up @@ -385,34 +383,9 @@ bool RISCVTargetLowering::lowerInterleaveIntrinsicToStore(

Value *Ptr, *VL;
Align Alignment;
if (auto *SI = dyn_cast<StoreInst>(Store)) {
assert(SI->isSimple());
Ptr = SI->getPointerOperand();
Alignment = SI->getAlign();
assert(!Mask && "Unexpected mask on a store");
Mask = Builder.getAllOnesMask(InVTy->getElementCount());
VL = isa<FixedVectorType>(InVTy)
? Builder.CreateElementCount(XLenTy, InVTy->getElementCount())
: Constant::getAllOnesValue(XLenTy);
} else {
auto *VPStore = cast<VPIntrinsic>(Store);
assert(VPStore->getIntrinsicID() == Intrinsic::vp_store &&
"Unexpected intrinsic");
Ptr = VPStore->getMemoryPointerParam();
Alignment = VPStore->getPointerAlignment().value_or(
DL.getABITypeAlign(InVTy->getElementType()));

assert(Mask && "vp.store needs a mask!");

Value *WideEVL = VPStore->getVectorLengthParam();
// Conservatively check if EVL is a multiple of factor, otherwise some
// (trailing) elements might be lost after the transformation.
if (!isMultipleOfN(WideEVL, DL, Factor))
return false;

auto *FactorC = ConstantInt::get(WideEVL->getType(), Factor);
VL = Builder.CreateZExt(Builder.CreateExactUDiv(WideEVL, FactorC), XLenTy);
}
if (!getMemOperands(Builder, Factor, InVTy, DL, XLenTy, Store, Ptr, Mask, VL,
Alignment))
return false;
Type *PtrTy = Ptr->getType();
unsigned AS = Ptr->getType()->getPointerAddressSpace();
if (!isLegalInterleavedAccessType(InVTy, Factor, Alignment, AS, DL))
Expand Down
Loading