@@ -22555,15 +22555,20 @@ bool RISCVTargetLowering::lowerInterleaveIntrinsicToStore(
2255522555///
2255622556/// NOTE: the deinterleave2 intrinsic won't be touched and is expected to be
2255722557/// removed by the caller
22558- bool RISCVTargetLowering::lowerInterleavedScalableLoad (
22559- VPIntrinsic *Load, Value *Mask, IntrinsicInst *DeinterleaveIntrin,
22558+ bool RISCVTargetLowering::lowerDeinterleavedIntrinsicToVPLoad (
22559+ VPIntrinsic *Load, Value *Mask,
2256022560 ArrayRef<Value *> DeInterleaveResults) const {
22561+ assert(Mask && "Expect a valid mask");
2256122562 assert(Load->getIntrinsicID() == Intrinsic::vp_load &&
2256222563 "Unexpected intrinsic");
2256322564
2256422565 const unsigned Factor = DeInterleaveResults.size();
2256522566
22566- auto *WideVTy = cast<VectorType>(Load->getType());
22567+ auto *WideVTy = dyn_cast<ScalableVectorType>(Load->getType());
22568+ // TODO: Support fixed vectors.
22569+ if (!WideVTy)
22570+ return false;
22571+
2256722572 unsigned WideNumElements = WideVTy->getElementCount().getKnownMinValue();
2256822573 assert(WideNumElements % Factor == 0 &&
2256922574 "ElementCount of a wide load must be divisible by interleave factor");
@@ -22605,10 +22610,6 @@ bool RISCVTargetLowering::lowerInterleavedScalableLoad(
2260522610 SmallVector<Value *> Operands;
2260622611 Operands.append({PoisonVal, Load->getArgOperand(0)});
2260722612
22608- if (!Mask)
22609- Mask = ConstantVector::getSplat(VTy->getElementCount(),
22610- ConstantInt::getTrue(Load->getContext()));
22611-
2261222613 Function *VlsegNFunc = Intrinsic::getOrInsertDeclaration(
2261322614 Load->getModule(), IntrMaskIds[Factor - 2],
2261422615 {VecTupTy, Mask->getType(), EVL->getType()});
@@ -22653,16 +22654,12 @@ bool RISCVTargetLowering::lowerInterleavedScalableLoad(
2265322654/// into
2265422655/// `<vscale x 8 x i32>`. This will resuling a simple unit stride store rather
2265522656/// than a segment store, which is more expensive in this case.
22656- static Value *foldInterleaved2OfConstSplats(IntrinsicInst *InterleaveIntrin ,
22657+ static Value *foldInterleaved2OfConstSplats(Value *Op0, Value *Op1 ,
2265722658 VectorType *VTy,
2265822659 const TargetLowering *TLI,
2265922660 Instruction *VPStore) {
22660- // We only handle Factor = 2 for now.
22661- assert(InterleaveIntrin->arg_size() == 2);
22662- auto *SplatVal0 = dyn_cast_or_null<ConstantInt>(
22663- getSplatValue(InterleaveIntrin->getArgOperand(0)));
22664- auto *SplatVal1 = dyn_cast_or_null<ConstantInt>(
22665- getSplatValue(InterleaveIntrin->getArgOperand(1)));
22661+ auto *SplatVal0 = dyn_cast_or_null<ConstantInt>(getSplatValue(Op0));
22662+ auto *SplatVal1 = dyn_cast_or_null<ConstantInt>(getSplatValue(Op1));
2266622663 if (!SplatVal0 || !SplatVal1)
2266722664 return nullptr;
2266822665
@@ -22711,15 +22708,19 @@ static Value *foldInterleaved2OfConstSplats(IntrinsicInst *InterleaveIntrin,
2271122708/// <vscale x 32 x i8> %load2, ptr %ptr,
2271222709/// %mask,
2271322710/// i64 %rvl)
22714- bool RISCVTargetLowering::lowerInterleavedScalableStore (
22715- VPIntrinsic *Store, Value *Mask, IntrinsicInst *InterleaveIntrin,
22711+ bool RISCVTargetLowering::lowerInterleavedIntrinsicToVPStore (
22712+ VPIntrinsic *Store, Value *Mask,
2271622713 ArrayRef<Value *> InterleaveOperands) const {
22714+ assert(Mask && "Expect a valid mask");
2271722715 assert(Store->getIntrinsicID() == Intrinsic::vp_store &&
2271822716 "Unexpected intrinsic");
2271922717
2272022718 const unsigned Factor = InterleaveOperands.size();
2272122719
22722- VectorType *VTy = cast<VectorType>(InterleaveOperands[0]->getType());
22720+ auto *VTy = dyn_cast<ScalableVectorType>(InterleaveOperands[0]->getType());
22721+ // TODO: Support fixed vectors.
22722+ if (!VTy)
22723+ return false;
2272322724
2272422725 // FIXME: Should pass alignment attribute from pointer, but vectorizer needs
2272522726 // to emit it first.
@@ -22731,9 +22732,10 @@ bool RISCVTargetLowering::lowerInterleavedScalableStore(
2273122732 return false;
2273222733
2273322734 if (Factor == 2)
22734- if (Value *BC =
22735- foldInterleaved2OfConstSplats(InterleaveIntrin, VTy, this, Store)) {
22736- InterleaveIntrin->replaceAllUsesWith(BC);
22735+ if (Value *BC = foldInterleaved2OfConstSplats(
22736+ InterleaveOperands[0], InterleaveOperands[1], VTy, this, Store)) {
22737+ // Store is guranteed to be the only user of the interleaved intrinsic.
22738+ Store->getOperand(0)->replaceAllUsesWith(BC);
2273722739 return true;
2273822740 }
2273922741
@@ -22770,10 +22772,6 @@ bool RISCVTargetLowering::lowerInterleavedScalableStore(
2277022772 Operands.push_back(StoredVal);
2277122773 Operands.push_back(Store->getArgOperand(1));
2277222774
22773- if (!Mask)
22774- Mask = ConstantVector::getSplat(VTy->getElementCount(),
22775- ConstantInt::getTrue(Store->getContext()));
22776-
2277722775 Function *VssegNFunc = Intrinsic::getOrInsertDeclaration(
2277822776 Store->getModule(), IntrMaskIds[Factor - 2],
2277922777 {VecTupTy, Mask->getType(), EVL->getType()});
0 commit comments