[llvm] 8ec7158 - [InstSimplify] simplify FP ops harder with FMF

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 12 06:26:33 PDT 2020


Author: Sanjay Patel
Date: 2020-03-12T09:13:28-04:00
New Revision: 8ec71585719d63223e1f796056b9ddee05b8263d

URL: https://github.com/llvm/llvm-project/commit/8ec71585719d63223e1f796056b9ddee05b8263d
DIFF: https://github.com/llvm/llvm-project/commit/8ec71585719d63223e1f796056b9ddee05b8263d.diff

LOG: [InstSimplify] simplify FP ops harder with FMF

This is part of the IR sibling for:
D75576

(I'm splitting part of the transform as a separate commit
to reduce risk. I don't know of any bugs that might be
exposed by this improved folding, but it's hard to see
those in advance...)

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/fp-nan.ll
    llvm/test/Transforms/InstSimplify/fp-undef.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 073ddb40dc5c..6144618003d8 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4603,9 +4603,22 @@ static Constant *propagateNaN(Constant *In) {
 /// Perform folds that are common to any floating-point operation. This implies
 /// transforms based on undef/NaN because the operation itself makes no
 /// 
diff erence to the result.
-static Constant *simplifyFPOp(ArrayRef<Value *> Ops) {
+static Constant *simplifyFPOp(ArrayRef<Value *> Ops,
+                              FastMathFlags FMF = FastMathFlags()) {
   for (Value *V : Ops) {
-    if (match(V, m_Undef()) || match(V, m_NaN()))
+    bool IsNan = match(V, m_NaN());
+    bool IsInf = match(V, m_Inf());
+    bool IsUndef = match(V, m_Undef());
+
+    // If this operation has 'nnan' or 'ninf' and at least 1 disallowed operand
+    // (TODO: an undef operand can be chosen to be Nan/Inf), then the result of
+    // this operation is poison. That result can be relaxed to undef.
+    if (FMF.noNaNs() && IsNan)
+      return UndefValue::get(V->getType());
+    if (FMF.noInfs() && IsInf)
+      return UndefValue::get(V->getType());
+
+    if (IsUndef || IsNan)
       return propagateNaN(cast<Constant>(V));
   }
   return nullptr;
@@ -4618,7 +4631,7 @@ static Value *SimplifyFAddInst(Value *Op0, Value *Op1, FastMathFlags FMF,
   if (Constant *C = foldOrCommuteConstant(Instruction::FAdd, Op0, Op1, Q))
     return C;
 
-  if (Constant *C = simplifyFPOp({Op0, Op1}))
+  if (Constant *C = simplifyFPOp({Op0, Op1}, FMF))
     return C;
 
   // fadd X, -0 ==> X
@@ -4665,7 +4678,7 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
   if (Constant *C = foldOrCommuteConstant(Instruction::FSub, Op0, Op1, Q))
     return C;
 
-  if (Constant *C = simplifyFPOp({Op0, Op1}))
+  if (Constant *C = simplifyFPOp({Op0, Op1}, FMF))
     return C;
 
   // fsub X, +0 ==> X
@@ -4707,7 +4720,7 @@ static Value *SimplifyFSubInst(Value *Op0, Value *Op1, FastMathFlags FMF,
 
 static Value *SimplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
                               const SimplifyQuery &Q, unsigned MaxRecurse) {
-  if (Constant *C = simplifyFPOp({Op0, Op1}))
+  if (Constant *C = simplifyFPOp({Op0, Op1}, FMF))
     return C;
 
   // fmul X, 1.0 ==> X
@@ -4774,7 +4787,7 @@ static Value *SimplifyFDivInst(Value *Op0, Value *Op1, FastMathFlags FMF,
   if (Constant *C = foldOrCommuteConstant(Instruction::FDiv, Op0, Op1, Q))
     return C;
 
-  if (Constant *C = simplifyFPOp({Op0, Op1}))
+  if (Constant *C = simplifyFPOp({Op0, Op1}, FMF))
     return C;
 
   // X / 1.0 -> X
@@ -4819,7 +4832,7 @@ static Value *SimplifyFRemInst(Value *Op0, Value *Op1, FastMathFlags FMF,
   if (Constant *C = foldOrCommuteConstant(Instruction::FRem, Op0, Op1, Q))
     return C;
 
-  if (Constant *C = simplifyFPOp({Op0, Op1}))
+  if (Constant *C = simplifyFPOp({Op0, Op1}, FMF))
     return C;
 
   // Unlike fdiv, the result of frem always matches the sign of the dividend.

diff  --git a/llvm/test/Transforms/InstSimplify/fp-nan.ll b/llvm/test/Transforms/InstSimplify/fp-nan.ll
index 4dd25237629a..7382fdfbe1a2 100644
--- a/llvm/test/Transforms/InstSimplify/fp-nan.ll
+++ b/llvm/test/Transforms/InstSimplify/fp-nan.ll
@@ -137,7 +137,7 @@ define <2 x double> @unary_fneg_nan_2(<2 x double> %x) {
 
 define float @fadd_nan_op0_nnan(float %x) {
 ; CHECK-LABEL: @fadd_nan_op0_nnan(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fadd nnan float 0x7FF8000000000000, %x
   ret float %r
@@ -145,7 +145,7 @@ define float @fadd_nan_op0_nnan(float %x) {
 
 define float @fadd_nan_op1_fast(float %x) {
 ; CHECK-LABEL: @fadd_nan_op1_fast(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fadd fast float %x, 0x7FF8000000000000
   ret float %r
@@ -153,7 +153,7 @@ define float @fadd_nan_op1_fast(float %x) {
 
 define float @fsub_nan_op0_fast(float %x) {
 ; CHECK-LABEL: @fsub_nan_op0_fast(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fsub fast float 0x7FF8000000000000, %x
   ret float %r
@@ -161,7 +161,7 @@ define float @fsub_nan_op0_fast(float %x) {
 
 define float @fsub_nan_op1_nnan(float %x) {
 ; CHECK-LABEL: @fsub_nan_op1_nnan(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fsub nnan float %x, 0x7FF8000000000000
   ret float %r
@@ -169,7 +169,7 @@ define float @fsub_nan_op1_nnan(float %x) {
 
 define float @fmul_nan_op0_nnan(float %x) {
 ; CHECK-LABEL: @fmul_nan_op0_nnan(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fmul nnan float 0x7FF8000000000000, %x
   ret float %r
@@ -177,7 +177,7 @@ define float @fmul_nan_op0_nnan(float %x) {
 
 define float @fmul_nan_op1_fast(float %x) {
 ; CHECK-LABEL: @fmul_nan_op1_fast(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fmul fast float %x, 0x7FF8000000000000
   ret float %r
@@ -185,7 +185,7 @@ define float @fmul_nan_op1_fast(float %x) {
 
 define float @fdiv_nan_op0_fast(float %x) {
 ; CHECK-LABEL: @fdiv_nan_op0_fast(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fdiv fast float 0x7FF8000000000000, %x
   ret float %r
@@ -193,7 +193,7 @@ define float @fdiv_nan_op0_fast(float %x) {
 
 define float @fdiv_nan_op1_nnan(float %x) {
 ; CHECK-LABEL: @fdiv_nan_op1_nnan(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = fdiv nnan float %x, 0x7FF8000000000000
   ret float %r
@@ -201,7 +201,7 @@ define float @fdiv_nan_op1_nnan(float %x) {
 
 define float @frem_nan_op0_nnan(float %x) {
 ; CHECK-LABEL: @frem_nan_op0_nnan(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = frem nnan float 0x7FF8000000000000, %x
   ret float %r
@@ -209,7 +209,7 @@ define float @frem_nan_op0_nnan(float %x) {
 
 define float @frem_nan_op1_fast(float %x) {
 ; CHECK-LABEL: @frem_nan_op1_fast(
-; CHECK-NEXT:    ret float 0x7FF8000000000000
+; CHECK-NEXT:    ret float undef
 ;
   %r = frem fast float %x, 0x7FF8000000000000
   ret float %r

diff  --git a/llvm/test/Transforms/InstSimplify/fp-undef.ll b/llvm/test/Transforms/InstSimplify/fp-undef.ll
index 1319c2e17624..cdf887f33639 100644
--- a/llvm/test/Transforms/InstSimplify/fp-undef.ll
+++ b/llvm/test/Transforms/InstSimplify/fp-undef.ll
@@ -179,23 +179,17 @@ define double @fadd_ninf_nan_op1(double %x) {
   ret double %r
 }
 
-; TODO: Should simplify to undef.
-
 define double @fdiv_ninf_inf_op0(double %x) {
 ; CHECK-LABEL: @fdiv_ninf_inf_op0(
-; CHECK-NEXT:    [[R:%.*]] = fdiv ninf double 0x7FF0000000000000, [[X:%.*]]
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double undef
 ;
   %r = fdiv ninf double 0x7ff0000000000000, %x
   ret double %r
 }
 
-; TODO: Should simplify to undef.
-
 define double @fadd_ninf_inf_op1(double %x) {
 ; CHECK-LABEL: @fadd_ninf_inf_op1(
-; CHECK-NEXT:    [[R:%.*]] = fadd ninf double [[X:%.*]], 0xFFF0000000000000
-; CHECK-NEXT:    ret double [[R]]
+; CHECK-NEXT:    ret double undef
 ;
   %r = fadd ninf double %x, 0xfff0000000000000
   ret double %r


        


More information about the llvm-commits mailing list