Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -166,10 +166,11 @@ static bool getShuffleDemandedElts(const ShuffleVectorInst *Shuf, const APInt &DemandedElts, APInt &DemandedLHS, APInt &DemandedRHS) { - // The length of scalable vectors is unknown at compile time, thus we - // cannot check their values - if (isa(Shuf->getType())) - return false; + if (isa(Shuf->getType())) { + assert(DemandedElts == APInt(1,1)); + DemandedLHS = DemandedRHS = DemandedElts; + return true; + } int NumElts = cast(Shuf->getOperand(0)->getType())->getNumElements(); @@ -206,13 +207,9 @@ static void computeKnownBits(const Value *V, KnownBits &Known, unsigned Depth, const Query &Q) { - // FIXME: We currently have no way to represent the DemandedElts of a scalable - // vector - if (isa(V->getType())) { - Known.resetAll(); - return; - } - + // Since the number of lanes in a scalable vector is unknown at compile time, + // we track one bit which is implicitly broadcast to all lanes. This means + // that all lanes in a scalable vector are considered demanded. auto *FVTy = dyn_cast(V->getType()); APInt DemandedElts = FVTy ? APInt::getAllOnes(FVTy->getNumElements()) : APInt(1, 1); @@ -1238,7 +1235,7 @@ // Look through a cast from narrow vector elements to wider type. // Examples: v4i32 -> v2i64, v3i8 -> v24 unsigned SubBitWidth = SrcVecTy->getScalarSizeInBits(); - if (BitWidth % SubBitWidth == 0) { + if (BitWidth % SubBitWidth == 0 && !isa(I->getType())) { // Known bits are automatically intersected across demanded elements of a // vector. So for example, if a bit is computed as known zero, it must be // zero across all demanded elements of the vector. @@ -1832,6 +1829,10 @@ break; } case Instruction::InsertElement: { + if (isa(I->getType())) { + Known.resetAll(); + return; + } const Value *Vec = I->getOperand(0); const Value *Elt = I->getOperand(1); auto *CIdx = dyn_cast(I->getOperand(2)); @@ -1948,9 +1949,8 @@ /// for all of the demanded elements in the vector specified by DemandedElts. void computeKnownBits(const Value *V, const APInt &DemandedElts, KnownBits &Known, unsigned Depth, const Query &Q) { - if (!DemandedElts || isa(V->getType())) { - // No demanded elts or V is a scalable vector, better to assume we don't - // know anything. + if (!DemandedElts) { + // No demanded elts, better to assume we don't know anything. Known.resetAll(); return; } @@ -1971,7 +1971,7 @@ "DemandedElt width should equal the fixed vector number of elements"); } else { assert(DemandedElts == APInt(1, 1) && - "DemandedElt width should be 1 for scalars"); + "DemandedElt width should be 1 for scalars or scalable vectors"); } Type *ScalarTy = Ty->getScalarType(); @@ -1998,6 +1998,7 @@ // Handle a constant vector by taking the intersection of the known bits of // each element. if (const ConstantDataVector *CDV = dyn_cast(V)) { + assert(!isa(V->getType())); // We know that CDV must be a vector of integers. Take the intersection of // each element. Known.Zero.setAllBits(); Known.One.setAllBits(); @@ -2012,6 +2013,7 @@ } if (const auto *CV = dyn_cast(V)) { + assert(!isa(V->getType())); // We know that CV must be a vector of integers. Take the intersection of // each element. Known.Zero.setAllBits(); Known.One.setAllBits(); Index: llvm/test/Transforms/InstCombine/add.ll =================================================================== --- llvm/test/Transforms/InstCombine/add.ll +++ llvm/test/Transforms/InstCombine/add.ll @@ -2338,7 +2338,7 @@ define @add_to_or_scalable( %in) { ; CHECK-LABEL: @add_to_or_scalable( ; CHECK-NEXT: [[SHL:%.*]] = shl [[IN:%.*]], shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) -; CHECK-NEXT: [[ADD:%.*]] = add [[SHL]], shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) +; CHECK-NEXT: [[ADD:%.*]] = or [[SHL]], shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) ; CHECK-NEXT: ret [[ADD]] ; %shl = shl %in, shufflevector ( insertelement ( poison, i32 1, i32 0), poison, zeroinitializer) Index: llvm/test/Transforms/InstCombine/intrinsics.ll =================================================================== --- llvm/test/Transforms/InstCombine/intrinsics.ll +++ llvm/test/Transforms/InstCombine/intrinsics.ll @@ -127,9 +127,7 @@ define @cttz_knownbits_scalable_vec( %arg) { ; CHECK-LABEL: @cttz_knownbits_scalable_vec( -; CHECK-NEXT: [[OR:%.*]] = and [[ARG:%.*]], shufflevector ( insertelement ( poison, i32 27, i32 0), poison, zeroinitializer) -; CHECK-NEXT: [[RES:%.*]] = icmp eq [[OR]], shufflevector ( insertelement ( poison, i32 20, i32 0), poison, zeroinitializer) -; CHECK-NEXT: ret [[RES]] +; CHECK-NEXT: ret zeroinitializer ; %or = or %arg, shufflevector ( insertelement ( poison, i32 4, i32 0), poison, zeroinitializer) %cnt = call @llvm.cttz.nxv1i32( %or, i1 true) nounwind readnone