Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -2961,8 +2961,8 @@ Assert(SrcTy->getPointerAddressSpace() != DestTy->getPointerAddressSpace(), "AddrSpaceCast must be between different address spaces", &I); if (auto *SrcVTy = dyn_cast(SrcTy)) - Assert(cast(SrcVTy)->getNumElements() == - cast(DestTy)->getNumElements(), + Assert(SrcVTy->getElementCount() == + cast(DestTy)->getElementCount(), "AddrSpaceCast vector pointer number of elements mismatch", &I); visitInstruction(I); } Index: llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -907,20 +907,21 @@ Value *VecOp; ConstantInt *Cst; if (match(Src, m_OneUse(m_ExtractElt(m_Value(VecOp), m_ConstantInt(Cst))))) { - auto *VecOpTy = cast(VecOp->getType()); - unsigned VecNumElts = VecOpTy->getNumElements(); + auto *VecOpTy = cast(VecOp->getType()); + auto VecElts = VecOpTy->getElementCount(); // A badly fit destination size would result in an invalid cast. if (SrcWidth % DestWidth == 0) { uint64_t TruncRatio = SrcWidth / DestWidth; - uint64_t BitCastNumElts = VecNumElts * TruncRatio; + uint64_t BitCastNumElts = VecElts.getKnownMinValue() * TruncRatio; uint64_t VecOpIdx = Cst->getZExtValue(); uint64_t NewIdx = DL.isBigEndian() ? (VecOpIdx + 1) * TruncRatio - 1 : VecOpIdx * TruncRatio; assert(BitCastNumElts <= std::numeric_limits::max() && "overflow 32-bits"); - auto *BitCastTo = FixedVectorType::get(DestTy, BitCastNumElts); + auto *BitCastTo = + VectorType::get(DestTy, BitCastNumElts, VecElts.isScalable()); Value *BitCast = Builder.CreateBitCast(VecOp, BitCastTo); return ExtractElementInst::Create(BitCast, Builder.getInt32(NewIdx)); } @@ -1567,13 +1568,13 @@ // TODO: Make these support undef elements. static Type *shrinkFPConstantVector(Value *V) { auto *CV = dyn_cast(V); - auto *CVVTy = dyn_cast(V->getType()); + auto *CVVTy = dyn_cast(V->getType()); if (!CV || !CVVTy) return nullptr; Type *MinType = nullptr; - unsigned NumElts = cast(CVVTy)->getNumElements(); + unsigned NumElts = CVVTy->getNumElements(); for (unsigned i = 0; i != NumElts; ++i) { auto *CFP = dyn_cast_or_null(CV->getAggregateElement(i)); if (!CFP) @@ -1974,12 +1975,9 @@ unsigned PtrSize = DL.getPointerSizeInBits(AS); if (TySize != PtrSize) { Type *IntPtrTy = DL.getIntPtrType(CI.getContext(), AS); - if (auto *VecTy = dyn_cast(Ty)) { - // Handle vectors of pointers. - // FIXME: what should happen for scalable vectors? - IntPtrTy = FixedVectorType::get( - IntPtrTy, cast(VecTy)->getNumElements()); - } + // Handle vectors of pointers. + if (auto *VecTy = dyn_cast(Ty)) + IntPtrTy = VectorType::get(IntPtrTy, VecTy->getElementCount()); Value *P = Builder.CreatePtrToInt(SrcOp, IntPtrTy); return CastInst::CreateIntegerCast(P, Ty, /*isSigned=*/false); @@ -2022,6 +2020,8 @@ // element size, or the input is a multiple of the output element size. // Convert the input type to have the same element type as the output. VectorType *SrcTy = cast(InVal->getType()); + if (!isa(SrcTy) || !isa(DestTy)) + return nullptr; if (SrcTy->getElementType() != DestTy->getElementType()) { // The input types don't need to be identical, but for now they must be the @@ -2660,13 +2660,11 @@ // a bitcast to a vector with the same # elts. Value *ShufOp0 = Shuf->getOperand(0); Value *ShufOp1 = Shuf->getOperand(1); - unsigned NumShufElts = - cast(Shuf->getType())->getNumElements(); - unsigned NumSrcVecElts = - cast(ShufOp0->getType())->getNumElements(); + auto ShufElts = cast(Shuf->getType())->getElementCount(); + auto SrcVecElts = cast(ShufOp0->getType())->getElementCount(); if (Shuf->hasOneUse() && DestTy->isVectorTy() && - cast(DestTy)->getNumElements() == NumShufElts && - NumShufElts == NumSrcVecElts) { + cast(DestTy)->getElementCount() == ShufElts && + ShufElts == SrcVecElts) { BitCastInst *Tmp; // If either of the operands is a cast from CI.getType(), then // evaluating the shuffle in the casted destination's type will allow @@ -2689,8 +2687,9 @@ // TODO: We should match the related pattern for bitreverse. if (DestTy->isIntegerTy() && DL.isLegalInteger(DestTy->getScalarSizeInBits()) && - SrcTy->getScalarSizeInBits() == 8 && NumShufElts % 2 == 0 && - Shuf->hasOneUse() && Shuf->isReverse()) { + SrcTy->getScalarSizeInBits() == 8 && + ShufElts.getKnownMinValue() % 2 == 0 && Shuf->hasOneUse() && + Shuf->isReverse()) { assert(ShufOp0->getType() == SrcTy && "Unexpected shuffle mask"); assert(isa(ShufOp1) && "Unexpected shuffle op"); Function *Bswap = @@ -2730,12 +2729,9 @@ Type *DestElemTy = DestTy->getElementType(); if (SrcTy->getElementType() != DestElemTy) { Type *MidTy = PointerType::get(DestElemTy, SrcTy->getAddressSpace()); - if (VectorType *VT = dyn_cast(CI.getType())) { - // Handle vectors of pointers. - // FIXME: what should happen for scalable vectors? - MidTy = FixedVectorType::get(MidTy, - cast(VT)->getNumElements()); - } + // Handle vectors of pointers. + if (VectorType *VT = dyn_cast(CI.getType())) + MidTy = VectorType::get(MidTy, VT->getElementCount()); Value *NewBitCast = Builder.CreateBitCast(Src, MidTy); return new AddrSpaceCastInst(NewBitCast, CI.getType()); Index: llvm/test/Transforms/InstCombine/addrspacecast.ll =================================================================== --- llvm/test/Transforms/InstCombine/addrspacecast.ll +++ llvm/test/Transforms/InstCombine/addrspacecast.ll @@ -102,6 +102,16 @@ ret <4 x float addrspace(2)*> %y } +define @combine_addrspacecast_types_scalevector( %x) nounwind { +; CHECK-LABEL: @combine_addrspacecast_types_scalevector( +; CHECK-NEXT: bitcast %x to +; CHECK-NEXT: addrspacecast %1 to +; CHECK-NEXT: ret + %y = addrspacecast %x to + ret %y +} + + define i32 @canonicalize_addrspacecast([16 x i32] addrspace(1)* %arr) { ; CHECK-LABEL: @canonicalize_addrspacecast( ; CHECK-NEXT: getelementptr [16 x i32], [16 x i32] addrspace(1)* %arr, i32 0, i32 0 Index: llvm/test/Transforms/InstCombine/ptr-int-cast.ll =================================================================== --- llvm/test/Transforms/InstCombine/ptr-int-cast.ll +++ llvm/test/Transforms/InstCombine/ptr-int-cast.ll @@ -35,6 +35,14 @@ ret <4 x i32> %p1 } +define @testvscale4( %arg) nounwind { +; CHECK-LABEL: @testvscale4( +; CHECK: ptrtoint %arg to +; CHECK: trunc %1 to + %p1 = ptrtoint %arg to + ret %p1 +} + define <4 x i128> @test5(<4 x i8*> %arg) nounwind { ; CHECK-LABEL: @test5( ; CHECK: ptrtoint <4 x i8*> %arg to <4 x i64> Index: llvm/test/Transforms/InstCombine/trunc-extractelement.ll =================================================================== --- llvm/test/Transforms/InstCombine/trunc-extractelement.ll +++ llvm/test/Transforms/InstCombine/trunc-extractelement.ll @@ -18,6 +18,23 @@ ret i32 %t } +define i32 @vscale_shrinkExtractElt_i64_to_i32_0( %x) { +; LE-LABEL: @vscale_shrinkExtractElt_i64_to_i32_0( +; LE-NEXT: [[TMP1:%.*]] = bitcast [[X:%.*]] to +; LE-NEXT: [[T:%.*]] = extractelement [[TMP1]], i32 0 +; LE-NEXT: ret i32 [[T]] +; +; BE-LABEL: @vscale_shrinkExtractElt_i64_to_i32_0( +; BE-NEXT: [[TMP1:%.*]] = bitcast [[X:%.*]] to +; BE-NEXT: [[T:%.*]] = extractelement [[TMP1]], i32 1 +; BE-NEXT: ret i32 [[T]] +; + %e = extractelement %x, i32 0 + %t = trunc i64 %e to i32 + ret i32 %t +} + + define i32 @shrinkExtractElt_i64_to_i32_1(<3 x i64> %x) { ; LE-LABEL: @shrinkExtractElt_i64_to_i32_1( ; LE-NEXT: [[TMP1:%.*]] = bitcast <3 x i64> [[X:%.*]] to <6 x i32> Index: llvm/test/Transforms/InstCombine/vec_shuffle.ll =================================================================== --- llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -59,6 +59,20 @@ ret float %r } +define float @testvscale6( %X) { +; CHECK-LABEL: @testvscale6( +; CHECK-NEXT: [[T:%.*]] = shufflevector [[X:%.*]], undef, zeroinitializer +; CHECK-NEXT: [[R:%.*]] = extractelement [[T]], i32 0 +; CHECK-NEXT: ret float [[R]] +; + %X1 = bitcast %X to + %t = shufflevector %X1, undef, zeroinitializer + %t2 = bitcast %t to + %r = extractelement %t2, i32 0 + ret float %r +} + + define <4 x float> @test7(<4 x float> %x) { ; CHECK-LABEL: @test7( ; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[X:%.*]], <4 x float> undef, <4 x i32>