[InstCombine] Add constant vector support to getMinimumFPType for visitFPTrunc.

This patch teaches getMinimumFPType to support shrinking a vector of ConstantFPs. This should improve our ability to combine vector fptrunc with fp binops.

Differential Revision: https://reviews.llvm.org/D43774

llvm-svn: 326729
This commit is contained in:
Craig Topper 2018-03-05 18:04:12 +00:00
parent 75bc70fb56
commit 8452faceae
2 changed files with 54 additions and 9 deletions

View File

@ -1435,6 +1435,36 @@ static Type *shrinkFPConstant(ConstantFP *CFP) {
return nullptr;
}
// Determine if this is a vector of ConstantFPs and if so, return the minimal
// type we can safely truncate all elements to.
// TODO: Make these support undef elements.
static Type *shrinkFPConstantVector(Value *V) {
auto *CV = dyn_cast<Constant>(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<ConstantFP>(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<FPExtInst>(V))
@ -1447,6 +1477,10 @@ static Type *getMinimumFPType(Value *V) {
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();
}

View File

@ -59,9 +59,7 @@ entry:
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 @@ entry:
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]], <double 0.000000e+00, double -0.000000e+00>
; CHECK-NEXT: [[TMP34:%.*]] = fptrunc <2 x double> [[TMP3]] to <2 x float>
; CHECK-NEXT: [[TMP34:%.*]] = fadd <2 x float> [[X:%.*]], <float 0.000000e+00, float -0.000000e+00>
; CHECK-NEXT: ret <2 x float> [[TMP34]]
;
entry:
@ -87,11 +83,26 @@ entry:
ret <2 x float> %tmp34
}
; Test with an undef element
; TODO: Support undef elements.
define <2 x float> @test6_undef(<2 x float> %x) nounwind {
; CHECK-LABEL: @test6_undef(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP1:%.*]] = fpext <2 x float> [[X:%.*]] to <2 x double>
; CHECK-NEXT: [[TMP3:%.*]] = fadd <2 x double> [[TMP1]], <double 0.000000e+00, double undef>
; CHECK-NEXT: [[TMP34:%.*]] = fptrunc <2 x double> [[TMP3]] to <2 x float>
; CHECK-NEXT: ret <2 x float> [[TMP34]]
;
entry:
%tmp1 = fpext <2 x float> %x to <2 x double>
%tmp3 = fadd <2 x double> %tmp1, <double 0.000000e+00, double undef>
%tmp34 = fptrunc <2 x double> %tmp3 to <2 x float>
ret <2 x float> %tmp34
}
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]], <double 0.000000e+00, double 2.049000e+03>
; CHECK-NEXT: [[R:%.*]] = fptrunc <2 x double> [[ADD]] to <2 x float>
; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[X:%.*]], <float 0.000000e+00, float 2.049000e+03>
; CHECK-NEXT: ret <2 x float> [[R]]
;
%ext = fpext <2 x float> %x to <2 x double>