Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1420,6 +1420,42 @@ return nullptr; } +static Constant *shrinkFPConstant(ConstantFP *CFP) { + if (CFP->getType() == Type::getPPC_FP128Ty(CFP->getContext())) + return nullptr; // No constant folding of this. + // See if the value can be truncated to half and then reextended. + if (Constant *NewCFP = fitsInFPType(CFP, APFloat::IEEEhalf())) + return NewCFP; + // See if the value can be truncated to float and then reextended. + if (Constant *NewCFP = fitsInFPType(CFP, APFloat::IEEEsingle())) + return NewCFP; + if (CFP->getType()->isDoubleTy()) + return nullptr; // Won't shrink. + if (Constant *NewCFP = fitsInFPType(CFP, APFloat::IEEEdouble())) + return NewCFP; + // Don't try to shrink to various long double types. + return nullptr; +} + +static Constant *shrinkFPConstantVector(Constant *CV) { + SmallVector Ops; + + 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; + Constant *NewCFP = shrinkFPConstant(CFP); + if (!NewCFP) + return nullptr; + // This was a shrinkable constant, save it. + Ops.push_back(NewCFP); + } + // We were able to shrink all elements of the vector, create a new vector + // with the smaller constants. + return ConstantVector::get(Ops); +} + /// Look through floating-point extensions until we get the source value. static Value *lookThroughFPExtensions(Value *V) { while (auto *FPExt = dyn_cast(V)) @@ -1428,21 +1464,15 @@ // If this value is a constant, return the constant in the smallest FP type // that can accurately represent it. This allows us to turn // (float)((double)X+2.0) into x+2.0f. - if (auto *CFP = dyn_cast(V)) { - if (CFP->getType() == Type::getPPC_FP128Ty(V->getContext())) - return V; // No constant folding of this. - // See if the value can be truncated to half and then reextended. - if (Value *V = fitsInFPType(CFP, APFloat::IEEEhalf())) - return V; - // See if the value can be truncated to float and then reextended. - if (Value *V = fitsInFPType(CFP, APFloat::IEEEsingle())) - return V; - if (CFP->getType()->isDoubleTy()) - return V; // Won't shrink. - if (Value *V = fitsInFPType(CFP, APFloat::IEEEdouble())) - return V; - // Don't try to shrink to various long double types. - } + if (auto *CFP = dyn_cast(V)) + if (Constant *NewCFP = shrinkFPConstant(CFP)) + return NewCFP; + + // Try to do the same for vectors of FP constants. + if (auto *CV = dyn_cast(V)) + if (CV->getType()->isVectorTy()) + if (Constant *NewCV = shrinkFPConstantVector(CV)) + return NewCV; return V; } Index: test/Transforms/InstCombine/fpextend.ll =================================================================== --- test/Transforms/InstCombine/fpextend.ll +++ test/Transforms/InstCombine/fpextend.ll @@ -84,9 +84,7 @@ ; CHECK-LABEL: @test5( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP:%.*]] = load <2 x float>, <2 x float>* @Z, align 8 -; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x float> [[TMP]] 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> [[TMP]], zeroinitializer ; CHECK-NEXT: store <2 x float> [[TMP34]], <2 x float>* @Z, align 8 ; CHECK-NEXT: ret void ; @@ -104,9 +102,7 @@ ; CHECK-LABEL: @test6( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP:%.*]] = load <2 x float>, <2 x float>* @Z, align 8 -; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x float> [[TMP]] 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> [[TMP]], ; CHECK-NEXT: store <2 x float> [[TMP34]], <2 x float>* @Z, align 8 ; CHECK-NEXT: ret void ;