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 @@ -1569,13 +1569,16 @@ // 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 fixed-width vectors we find the min-type by looking + // through the constant values of the vector. for (unsigned i = 0; i != NumElts; ++i) { auto *CFP = dyn_cast_or_null(CV->getAggregateElement(i)); if (!CFP) @@ -1607,7 +1610,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: %[[FADD:.*]] = fadd %a, shufflevector ( insertelement ( undef, float -1.000000e+00, i32 0), undef, zeroinitializer) + ; CHECK-NEXT: ret %[[FADD]] + %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 +}