[PATCH] D67721: [InstSimplify] fold fma/fmuladd with a NaN operand

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 18 10:40:45 PDT 2019


spatel created this revision.
spatel added reviewers: fhahn, cameron.mcinally, arsenm, reames.
Herald added subscribers: hiraditya, wdng, mcrosier.
Herald added a project: LLVM.

I'm not sure if/how adding these simplifications will impact D67351 <https://reviews.llvm.org/D67351>, but we should have the basic cases within InstSimplify because that potentially makes other passes like GVN better.

This is intended to be similar to the constant folding results from D67446 <https://reviews.llvm.org/D67446> and earlier, but not all operands are constant in these tests, so the responsibility for folding is left to InstSimplify.


https://reviews.llvm.org/D67721

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstSimplify/call.ll


Index: llvm/test/Transforms/InstSimplify/call.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/call.ll
+++ llvm/test/Transforms/InstSimplify/call.ll
@@ -747,8 +747,7 @@
 
 define double @fma_nan_op0(double %x, double %y) {
 ; CHECK-LABEL: @fma_nan_op0(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double 0x7FF8000000000000, double [[X:%.*]], double [[Y:%.*]])
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = call double @llvm.fma.f64(double 0x7ff8000000000000, double %x, double %y)
   ret double %r
@@ -756,8 +755,7 @@
 
 define double @fma_nan_op1(double %x, double %y) {
 ; CHECK-LABEL: @fma_nan_op1(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double [[X:%.*]], double 0x7FF8000000000001, double [[Y:%.*]])
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000001
 ;
   %r = call double @llvm.fma.f64(double %x, double 0x7ff8000000000001, double %y)
   ret double %r
@@ -765,8 +763,7 @@
 
 define double @fma_nan_op2(double %x, double %y) {
 ; CHECK-LABEL: @fma_nan_op2(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double [[X:%.*]], double [[Y:%.*]], double 0x7FF8000000000002)
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000002
 ;
   %r = call double @llvm.fma.f64(double %x, double %y, double 0x7ff8000000000002)
   ret double %r
@@ -774,8 +771,7 @@
 
 define double @fmuladd_nan_op0_op1(double %x) {
 ; CHECK-LABEL: @fmuladd_nan_op0_op1(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double 0x7FF8000000001234, double 0x7FF800000000DEAD, double [[X:%.*]])
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000001234
 ;
   %r = call double @llvm.fmuladd.f64(double 0x7ff8000000001234, double 0x7ff800000000dead, double %x)
   ret double %r
@@ -783,8 +779,7 @@
 
 define double @fmuladd_nan_op0_op2(double %x) {
 ; CHECK-LABEL: @fmuladd_nan_op0_op2(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double 0x7FF8000000005678, double [[X:%.*]], double 0x7FF800000000DEAD)
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000005678
 ;
   %r = call double @llvm.fmuladd.f64(double 0x7ff8000000005678, double %x, double 0x7ff800000000dead)
   ret double %r
@@ -792,8 +787,7 @@
 
 define double @fmuladd_nan_op1_op2(double %x) {
 ; CHECK-LABEL: @fmuladd_nan_op1_op2(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double [[X:%.*]], double 0x7FF80000AAAAAAAA, double 0x7FF800000000DEAD)
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF80000AAAAAAAA
 ;
   %r = call double @llvm.fmuladd.f64(double %x, double 0x7ff80000aaaaaaaa, double 0x7ff800000000dead)
   ret double %r
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5151,6 +5151,25 @@
     }
     return nullptr;
   }
+  case Intrinsic::fma:
+  case Intrinsic::fmuladd: {
+    // If any operand is NaN, return that NaN value. This arbitrarily
+    // propagates the first NaN value encountered if there is more than 1.
+    Value *Op0 = Call->getArgOperand(0);
+    Value *Op1 = Call->getArgOperand(1);
+    Value *Op2 = Call->getArgOperand(2);
+    if (match(Op0, m_NaN()))
+      return Op0;
+    if (match(Op1, m_NaN()))
+      return Op1;
+    if (match(Op2, m_NaN()))
+      return Op2;
+
+    // TODO: Handle cases where non-NaN multiplicand operands and/or addend are
+    //       known to produce a NaN.
+
+    return nullptr;
+  }
   default:
     return nullptr;
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67721.220701.patch
Type: text/x-patch
Size: 3703 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190918/2903162f/attachment.bin>


More information about the llvm-commits mailing list