[llvm] r371735 - [ConstProp] allow folding for fma that produces NaN

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 12 07:10:50 PDT 2019


Author: spatel
Date: Thu Sep 12 07:10:50 2019
New Revision: 371735

URL: http://llvm.org/viewvc/llvm-project?rev=371735&view=rev
Log:
[ConstProp] allow folding for fma that produces NaN

Folding for fma/fmuladd was added here:
rL202914
...and as seen in existing/unchanged tests, that works to propagate NaN
if it's already an input, but we should fold an fma() that creates NaN too.

>From IEEE-754-2008 7.2 "Invalid Operation", there are 2 clauses that apply
to fma, so I added tests for those patterns:

  c) fusedMultiplyAdd: fusedMultiplyAdd(0, ∞, c) or fusedMultiplyAdd(∞, 0, c)
     unless c is a quiet NaN; if c is a quiet NaN then it is implementation
     defined whether the invalid operation exception is signaled
  d) addition or subtraction or fusedMultiplyAdd: magnitude subtraction of
     infinities, such as: addition(+∞, −∞)

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

Modified:
    llvm/trunk/include/llvm/ADT/APFloat.h
    llvm/trunk/lib/Analysis/ConstantFolding.cpp
    llvm/trunk/test/Transforms/ConstProp/fma.ll

Modified: llvm/trunk/include/llvm/ADT/APFloat.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=371735&r1=371734&r2=371735&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/APFloat.h (original)
+++ llvm/trunk/include/llvm/ADT/APFloat.h Thu Sep 12 07:10:50 2019
@@ -192,6 +192,11 @@ struct APFloatBase {
   /// IEEE-754R 7: Default exception handling.
   ///
   /// opUnderflow or opOverflow are always returned or-ed with opInexact.
+  ///
+  /// APFloat models this behavior specified by IEEE-754:
+  ///   "For operations producing results in floating-point format, the default
+  ///    result of an operation that signals the invalid operation exception
+  ///    shall be a quiet NaN."
   enum opStatus {
     opOK = 0x00,
     opInvalidOp = 0x01,

Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=371735&r1=371734&r2=371735&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original)
+++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Thu Sep 12 07:10:50 2019
@@ -2243,13 +2243,9 @@ static Constant *ConstantFoldScalarCall3
         case Intrinsic::fma:
         case Intrinsic::fmuladd: {
           APFloat V = Op1->getValueAPF();
-          APFloat::opStatus s = V.fusedMultiplyAdd(Op2->getValueAPF(),
-                                                   Op3->getValueAPF(),
-                                                   APFloat::rmNearestTiesToEven);
-          if (s != APFloat::opInvalidOp)
-            return ConstantFP::get(Ty->getContext(), V);
-
-          return nullptr;
+          V.fusedMultiplyAdd(Op2->getValueAPF(), Op3->getValueAPF(),
+                             APFloat::rmNearestTiesToEven);
+          return ConstantFP::get(Ty->getContext(), V);
         }
         }
       }

Modified: llvm/trunk/test/Transforms/ConstProp/fma.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/fma.ll?rev=371735&r1=371734&r2=371735&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/ConstProp/fma.ll (original)
+++ llvm/trunk/test/Transforms/ConstProp/fma.ll Thu Sep 12 07:10:50 2019
@@ -129,8 +129,7 @@ define double @test_Inf_4()  {
 
 define double @inf_product_opposite_inf_addend_1()  {
 ; CHECK-LABEL: @inf_product_opposite_inf_addend_1(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 7.000000e+00, double 0xFFF0000000000000, double 0x7FF0000000000000)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 7.0, double 0xFFF0000000000000, double 0x7FF0000000000000)
   ret double %1
@@ -140,8 +139,7 @@ define double @inf_product_opposite_inf_
 
 define double @inf_product_opposite_inf_addend_2()  {
 ; CHECK-LABEL: @inf_product_opposite_inf_addend_2(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 7.000000e+00, double 0x7FF0000000000000, double 0xFFF0000000000000)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 7.0, double 0x7FF0000000000000, double 0xFFF0000000000000)
   ret double %1
@@ -151,8 +149,7 @@ define double @inf_product_opposite_inf_
 
 define double @inf_product_opposite_inf_addend_3()  {
 ; CHECK-LABEL: @inf_product_opposite_inf_addend_3(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0xFFF0000000000000, double 4.200000e+01, double 0x7FF0000000000000)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double 42.0, double 0x7FF0000000000000)
   ret double %1
@@ -162,8 +159,7 @@ define double @inf_product_opposite_inf_
 
 define double @inf_product_opposite_inf_addend_4()  {
 ; CHECK-LABEL: @inf_product_opposite_inf_addend_4(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0x7FF0000000000000, double 4.200000e+01, double 0xFFF0000000000000)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double 42.0, double 0xFFF0000000000000)
   ret double %1
@@ -173,8 +169,7 @@ define double @inf_product_opposite_inf_
 
 define double @inf_times_zero_1()  {
 ; CHECK-LABEL: @inf_times_zero_1(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0.000000e+00, double 0xFFF0000000000000, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0.0, double 0xFFF0000000000000, double 42.0)
   ret double %1
@@ -184,8 +179,7 @@ define double @inf_times_zero_1()  {
 
 define double @inf_times_zero_2()  {
 ; CHECK-LABEL: @inf_times_zero_2(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0.000000e+00, double 0x7FF0000000000000, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0.0, double 0x7FF0000000000000, double 42.0)
   ret double %1
@@ -195,8 +189,7 @@ define double @inf_times_zero_2()  {
 
 define double @inf_times_zero_3()  {
 ; CHECK-LABEL: @inf_times_zero_3(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0xFFF0000000000000, double 0.000000e+00, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double 0.0, double 42.0)
   ret double %1
@@ -206,8 +199,7 @@ define double @inf_times_zero_3()  {
 
 define double @inf_times_zero_4()  {
 ; CHECK-LABEL: @inf_times_zero_4(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0x7FF0000000000000, double 0.000000e+00, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double 0.0, double 42.0)
   ret double %1
@@ -217,8 +209,7 @@ define double @inf_times_zero_4()  {
 
 define double @inf_times_zero_5()  {
 ; CHECK-LABEL: @inf_times_zero_5(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double -0.000000e+00, double 0xFFF0000000000000, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double -0.0, double 0xFFF0000000000000, double 42.0)
   ret double %1
@@ -228,8 +219,7 @@ define double @inf_times_zero_5()  {
 
 define double @inf_times_zero_6()  {
 ; CHECK-LABEL: @inf_times_zero_6(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double -0.000000e+00, double 0x7FF0000000000000, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double -0.0, double 0x7FF0000000000000, double 42.0)
   ret double %1
@@ -239,8 +229,7 @@ define double @inf_times_zero_6()  {
 
 define double @inf_times_zero_7()  {
 ; CHECK-LABEL: @inf_times_zero_7(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0xFFF0000000000000, double -0.000000e+00, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0xFFF0000000000000, double -0.0, double 42.0)
   ret double %1
@@ -250,10 +239,8 @@ define double @inf_times_zero_7()  {
 
 define double @inf_times_zero_8()  {
 ; CHECK-LABEL: @inf_times_zero_8(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.fma.f64(double 0x7FF0000000000000, double -0.000000e+00, double 4.200000e+01)
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %1 = call double @llvm.fma.f64(double 0x7FF0000000000000, double -0.0, double 42.0)
   ret double %1
 }
-




More information about the llvm-commits mailing list