diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index 80d5168ae961a..91d3776487f27 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -3743,7 +3743,7 @@ InstructionCost AArch64TTIImpl::getInterleavedMemoryOpCost( assert(Factor >= 2 && "Invalid interleave factor"); auto *VecVTy = cast(VecTy); - if (VecTy->isScalableTy() && (!ST->hasSVE() || Factor != 2)) + if (VecTy->isScalableTy() && !ST->hasSVE()) return InstructionCost::getInvalid(); // Vectorization for masked interleaved accesses is only enabled for scalable diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp index a61461681f79e..34110b0f46107 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp @@ -675,8 +675,6 @@ InstructionCost RISCVTTIImpl::getInterleavedMemoryOpCost( unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond, bool UseMaskForGaps) { - if (isa(VecTy) && Factor != 2) - return InstructionCost::getInvalid(); // The interleaved memory access pass will lower interleaved memory ops (i.e // a load and store followed by a specific shuffle) to vlseg/vsseg diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 001c8987667df..f766070f9aaf4 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3406,6 +3406,7 @@ bool LoopVectorizationCostModel::interleavedAccessCanBeWidened( "Decision should not be set yet."); auto *Group = getInterleavedAccessGroup(I); assert(Group && "Must have a group."); + unsigned InterleaveFactor = Group->getFactor(); // If the instruction's allocated size doesn't equal it's type size, it // requires padding and will be scalarized. @@ -3414,9 +3415,14 @@ bool LoopVectorizationCostModel::interleavedAccessCanBeWidened( if (hasIrregularType(ScalarTy, DL)) return false; + // We currently only know how to emit interleave/deinterleave with + // Factor=2 for scalable vectors. This is purely an implementation + // limit. + if (VF.isScalable() && InterleaveFactor != 2) + return false; + // If the group involves a non-integral pointer, we may not be able to // losslessly cast all values to a common type. - unsigned InterleaveFactor = Group->getFactor(); bool ScalarNI = DL.isNonIntegralPointerType(ScalarTy); for (unsigned Idx = 0; Idx < InterleaveFactor; Idx++) { Instruction *Member = Group->getMember(Idx);