[InstSimplify] fold fma/fmuladd with a NaN or undef operand
authorSanjay Patel <spatel@rotateright.com>
Wed, 2 Oct 2019 12:12:02 +0000 (12:12 +0000)
committerSanjay Patel <spatel@rotateright.com>
Wed, 2 Oct 2019 12:12:02 +0000 (12:12 +0000)
This is intended to be similar to the constant folding results from
D67446
and earlier, but not all operands are constant in these tests, so the
responsibility for folding is left to InstSimplify.

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

llvm-svn: 373455

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

index a2c622e..ca00adf 100644 (file)
@@ -5186,6 +5186,15 @@ static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) {
     }
     return nullptr;
   }
+  case Intrinsic::fma:
+  case Intrinsic::fmuladd: {
+    Value *Op0 = Call->getArgOperand(0);
+    Value *Op1 = Call->getArgOperand(1);
+    Value *Op2 = Call->getArgOperand(2);
+    if (Value *V = simplifyFPOp({ Op0, Op1, Op2 }))
+      return V;
+    return nullptr;
+  }
   default:
     return nullptr;
   }
index 3083e60..2fc0841 100644 (file)
@@ -747,8 +747,7 @@ declare double @llvm.fmuladd.f64(double,double,double)
 
 define double @fma_undef_op0(double %x, double %y) {
 ; CHECK-LABEL: @fma_undef_op0(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double undef, double [[X:%.*]], double [[Y:%.*]])
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = call double @llvm.fma.f64(double undef, double %x, double %y)
   ret double %r
@@ -756,8 +755,7 @@ define double @fma_undef_op0(double %x, double %y) {
 
 define double @fma_undef_op1(double %x, double %y) {
 ; CHECK-LABEL: @fma_undef_op1(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double [[X:%.*]], double undef, double [[Y:%.*]])
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = call double @llvm.fma.f64(double %x, double undef, double %y)
   ret double %r
@@ -765,8 +763,7 @@ define double @fma_undef_op1(double %x, double %y) {
 
 define double @fma_undef_op2(double %x, double %y) {
 ; CHECK-LABEL: @fma_undef_op2(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fma.f64(double [[X:%.*]], double [[Y:%.*]], double undef)
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = call double @llvm.fma.f64(double %x, double %y, double undef)
   ret double %r
@@ -774,8 +771,7 @@ define double @fma_undef_op2(double %x, double %y) {
 
 define double @fmuladd_undef_op0(double %x, double %y) {
 ; CHECK-LABEL: @fmuladd_undef_op0(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double undef, double [[X:%.*]], double [[Y:%.*]])
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = call double @llvm.fmuladd.f64(double undef, double %x, double %y)
   ret double %r
@@ -783,8 +779,7 @@ define double @fmuladd_undef_op0(double %x, double %y) {
 
 define double @fmuladd_undef_op1(double %x, double %y) {
 ; CHECK-LABEL: @fmuladd_undef_op1(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double [[X:%.*]], double undef, double [[Y:%.*]])
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = call double @llvm.fmuladd.f64(double %x, double undef, double %y)
   ret double %r
@@ -792,8 +787,7 @@ define double @fmuladd_undef_op1(double %x, double %y) {
 
 define double @fmuladd_undef_op2(double %x, double %y) {
 ; CHECK-LABEL: @fmuladd_undef_op2(
-; CHECK-NEXT:    [[R:%.*]] = call double @llvm.fmuladd.f64(double [[X:%.*]], double [[Y:%.*]], double undef)
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double 0x7FF8000000000000
 ;
   %r = call double @llvm.fmuladd.f64(double %x, double %y, double undef)
   ret double %r
@@ -801,8 +795,7 @@ define double @fmuladd_undef_op2(double %x, double %y) {
 
 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
@@ -810,8 +803,7 @@ define double @fma_nan_op0(double %x, double %y) {
 
 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
@@ -819,8 +811,7 @@ define double @fma_nan_op1(double %x, double %y) {
 
 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
@@ -828,8 +819,7 @@ define double @fma_nan_op2(double %x, double %y) {
 
 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
@@ -837,8 +827,7 @@ define double @fmuladd_nan_op0_op1(double %x) {
 
 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
@@ -846,8 +835,7 @@ define double @fmuladd_nan_op0_op2(double %x) {
 
 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