[InstCombine] Add constant vector support to getMinimumFPType for visitFPTrunc.
authorCraig Topper <craig.topper@intel.com>
Mon, 5 Mar 2018 18:04:12 +0000 (18:04 +0000)
committerCraig Topper <craig.topper@intel.com>
Mon, 5 Mar 2018 18:04:12 +0000 (18:04 +0000)
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

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
llvm/test/Transforms/InstCombine/fpextend.ll

index fa47be2491d27220fc1e7c470a04b6ab3608e120..1bc5a5706ef19896d196f1b5cf84d8d1a3109c71 100644 (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();
 }
 
index 98dec674d36d56bb2228fff8d002d13b515e83d2..88401504f570f568a7813a0a6ff51eeac687da81 100644 (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,23 +73,36 @@ entry:
 define <2 x float> @test6(<2 x float> %x) nounwind  {
 ; CHECK-LABEL: @test6(
 ; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP34:%.*]] = fadd <2 x float> [[X:%.*]], <float 0.000000e+00, float -0.000000e+00>
+; 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 -0.000000e+00>
+  %tmp34 = fptrunc <2 x double> %tmp3 to <2 x float>
+  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 -0.000000e+00>
+; 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 -0.000000e+00>
+  %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>