Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1435,6 +1435,35 @@ return nullptr; } +// Determine if this is a vector of ConstantFPs and if so, return the minimal +// type we can safely truncate all elements to. +static Type *shrinkFPConstantVector(Value *V) { + auto *CV = dyn_cast(V); + if (!CV || !CV->getType()->isVectorTy()) + return nullptr; + + Type *MinType = nullptr; + + unsigned NumElts = CV->getType()->getVectorNumElements(); + for (unsigned i = 0; i != NumElts; ++i) { + auto *CFP = dyn_cast_or_null(CV->getAggregateElement(i)); + if (!CFP) + return nullptr; + + Type *T = shrinkFPConstant(CFP); + if (!T) + return nullptr; + + // If we haven't found a type yet or this type has a larger mantissa than + // our previous type, this is our new minimal type. + if (!MinType || T->getFPMantissaWidth() > MinType->getFPMantissaWidth()) + MinType = T; + } + + // Make a vector type from the minimal type. + return VectorType::get(MinType, NumElts); +} + /// Find the minimum FP type we can safely truncate to. static Type *getMinimumFPType(Value *V) { if (auto *FPExt = dyn_cast(V)) @@ -1447,6 +1476,10 @@ if (Type *T = shrinkFPConstant(CFP)) return T; + // Try to shrink a vector of FP constants. + if (Type *T = shrinkFPConstantVector(V)) + return T; + return V->getType(); } Index: test/Transforms/InstCombine/fpextend.ll =================================================================== --- test/Transforms/InstCombine/fpextend.ll +++ test/Transforms/InstCombine/fpextend.ll @@ -59,9 +59,7 @@ define <2 x float> @test5(<2 x float> %x) nounwind { ; CHECK-LABEL: @test5( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double> -; CHECK-NEXT: [[TMP3:%.*]] = fadd <2 x double> [[TMP1]], zeroinitializer -; CHECK-NEXT: [[TMP34:%.*]] = fptrunc <2 x double> [[TMP3]] to <2 x float> +; CHECK-NEXT: [[TMP34:%.*]] = fadd <2 x float> [[X:%.*]], zeroinitializer ; CHECK-NEXT: ret <2 x float> [[TMP34]] ; entry: @@ -75,9 +73,7 @@ define <2 x float> @test6(<2 x float> %x) nounwind { ; CHECK-LABEL: @test6( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double> -; CHECK-NEXT: [[TMP3:%.*]] = fadd <2 x double> [[TMP1]], -; CHECK-NEXT: [[TMP34:%.*]] = fptrunc <2 x double> [[TMP3]] to <2 x float> +; CHECK-NEXT: [[TMP34:%.*]] = fadd <2 x float> [[X:%.*]], ; CHECK-NEXT: ret <2 x float> [[TMP34]] ; entry: @@ -89,9 +85,7 @@ define <2 x float> @not_half_shrinkable(<2 x float> %x) { ; CHECK-LABEL: @not_half_shrinkable( -; CHECK-NEXT: [[EXT:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double> -; CHECK-NEXT: [[ADD:%.*]] = fadd <2 x double> [[EXT]], -; CHECK-NEXT: [[R:%.*]] = fptrunc <2 x double> [[ADD]] to <2 x float> +; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[X:%.*]], ; CHECK-NEXT: ret <2 x float> [[R]] ; %ext = fpext <2 x float> %x to <2 x double>