diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1575,13 +1575,22 @@ Type *MinType = nullptr; - unsigned NumElts = cast(CVVTy)->getNumElements(); - for (unsigned i = 0; i != NumElts; ++i) { + auto EC = cast(CVVTy)->getElementCount(); + + // We only can correctly find a MinType for a ScalableVector if the vector + // is a splat-vector, otherwise we can't shrink due to the runtime-defined + // vscale value. + if (EC.isScalable()) + return nullptr; + + // For fixed-width vectors we find the min-type by looking + // through the constant values of the vector. + for (unsigned i = 0; i != EC.getFixedValue(); ++i) { auto *CFP = dyn_cast_or_null(CV->getAggregateElement(i)); if (!CFP) return nullptr; - Type *T = shrinkFPConstant(CFP); + auto *T = shrinkFPConstant(CFP); if (!T) return nullptr; @@ -1591,8 +1600,7 @@ MinType = T; } - // Make a vector type from the minimal type. - return FixedVectorType::get(MinType, NumElts); + return FixedVectorType::get(MinType, EC.getFixedValue()); } /// Find the minimum FP type we can safely truncate to. @@ -1607,7 +1615,15 @@ if (Type *T = shrinkFPConstant(CFP)) return T; - // Try to shrink a vector of FP constants. + // We only can correctly find a MinType for a ScalableVector if the vector + // is a splat-vector, otherwise we can't shrink due to the runtime-defined + // vscale value. Vectors of this type will be wrapped in a fpext constant. + if (auto *FPCExt = dyn_cast(V)) + if (FPCExt->getOpcode() == Instruction::FPExt) + return FPCExt->getOperand(0)->getType(); + + // Try to shrink a vector of FP constants. This returns nullptr on scalable + // vectors if (Type *T = shrinkFPConstantVector(V)) return T; diff --git a/llvm/test/Transforms/InstCombine/AArch64/sve-splat.ll b/llvm/test/Transforms/InstCombine/AArch64/sve-splat.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/AArch64/sve-splat.ll @@ -0,0 +1,17 @@ +; RUN: opt -instcombine -mtriple=aarch64-linux-gnu -mattr=+sve -S -o - < %s 2>%t | FileCheck %s +; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it. +; WARN-NOT: warning + +define @shrink_splat_scalable_extend( %a) { + ; CHECK-LABEL: @shrink_splat_scalable_extend + ; CHECK-NEXT: %1 = fadd %a, shufflevector ( insertelement ( undef, float -1.000000e+00, i32 0), undef, zeroinitializer) + ; CHECK-NEXT: ret %1 + %1 = shufflevector insertelement ( undef, float -1.000000e+00, i32 0), undef, zeroinitializer + %2 = fpext %a to + %3 = fpext %1 to + %4 = fadd %2, %3 + %5 = fptrunc %4 to + ret %5 +}