[llvm] 7526376 - [InstSimplify] allow folds for fmin/fmax with 'ninf'

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 08:18:21 PDT 2020


Author: Sanjay Patel
Date: 2020-09-14T11:18:08-04:00
New Revision: 7526376164801cc758c94217931ab025bc226b0e

URL: https://github.com/llvm/llvm-project/commit/7526376164801cc758c94217931ab025bc226b0e
DIFF: https://github.com/llvm/llvm-project/commit/7526376164801cc758c94217931ab025bc226b0e.diff

LOG: [InstSimplify] allow folds for fmin/fmax with 'ninf'

maxnum(ninf X, +FLT_MAX) --> +FLT_MAX
minnum(ninf X, -FLT_MAX) --> -FLT_MAX

This is based on the similar codegen transform proposed in:
D87571

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/fminmax-folds.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 9933360a3a1a..88cfe5a1fa85 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5455,23 +5455,30 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
     if (Q.isUndefValue(Op1))
       return Op0;
 
-    // If an argument is NaN, return other or NaN appropriately.
     bool PropagateNaN = IID == Intrinsic::minimum || IID == Intrinsic::maximum;
+    bool IsMin = IID == Intrinsic::minimum || IID == Intrinsic::minnum;
+
+    // minnum(X, nan) -> X
+    // maxnum(X, nan) -> X
+    // minimum(X, nan) -> nan
+    // maximum(X, nan) -> nan
     if (match(Op1, m_NaN()))
       return PropagateNaN ? Op1 : Op0;
 
-    // min(X, -Inf) --> -Inf
-    // max(X, +Inf) --> +Inf
-    bool UseNegInf = IID == Intrinsic::minnum || IID == Intrinsic::minimum;
+    // In the following folds, inf can be replaced with the largest finite
+    // float, if the ninf flag is set.
     const APFloat *C;
-    if (match(Op1, m_APFloat(C)) && C->isInfinity() &&
-        C->isNegative() == UseNegInf && !PropagateNaN)
-      return ConstantFP::getInfinity(ReturnType, UseNegInf);
-
-    // TODO: minimum(nnan x, inf) -> x
-    // TODO: minnum(nnan ninf x, flt_max) -> x
-    // TODO: maximum(nnan x, -inf) -> x
-    // TODO: maxnum(nnan ninf x, -flt_max) -> x
+    if (match(Op1, m_APFloat(C)) &&
+        (C->isInfinity() || (Q.CxtI->hasNoInfs() && C->isLargest()))) {
+      // min(X, -Inf) --> -Inf
+      // max(X, +Inf) --> +Inf
+      if (C->isNegative() == IsMin && !PropagateNaN)
+        return ConstantFP::get(ReturnType, *C);
+      // TODO: minimum(nnan x, inf) -> x
+      // TODO: minnum(nnan ninf x, flt_max) -> x
+      // TODO: maximum(nnan x, -inf) -> x
+      // TODO: maxnum(nnan ninf x, -flt_max) -> x
+    }
 
     // Min/max of the same operation with common operand:
     // m(m(X, Y)), X --> m(X, Y) (4 commuted variants)

diff  --git a/llvm/test/Transforms/InstSimplify/fminmax-folds.ll b/llvm/test/Transforms/InstSimplify/fminmax-folds.ll
index 5d502d22ccca..3811ae81e8d3 100644
--- a/llvm/test/Transforms/InstSimplify/fminmax-folds.ll
+++ b/llvm/test/Transforms/InstSimplify/fminmax-folds.ll
@@ -344,8 +344,7 @@ define float @test_minnum_const_max_ninf(float %x) {
 
 define float @test_maxnum_const_max_ninf(float %x) {
 ; CHECK-LABEL: @test_maxnum_const_max_ninf(
-; CHECK-NEXT:    [[R:%.*]] = call ninf float @llvm.maxnum.f32(float [[X:%.*]], float 0x47EFFFFFE0000000)
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x47EFFFFFE0000000
 ;
   %r = call ninf float @llvm.maxnum.f32(float %x, float 0x47efffffe0000000)
   ret float %r
@@ -371,8 +370,7 @@ define float @test_minimum_const_max_ninf(float %x) {
 
 define float @test_minnum_const_neg_max_ninf(float %x) {
 ; CHECK-LABEL: @test_minnum_const_neg_max_ninf(
-; CHECK-NEXT:    [[R:%.*]] = call ninf float @llvm.minnum.f32(float [[X:%.*]], float 0xC7EFFFFFE0000000)
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0xC7EFFFFFE0000000
 ;
   %r = call ninf float @llvm.minnum.f32(float %x, float 0xc7efffffe0000000)
   ret float %r
@@ -416,8 +414,7 @@ define float @test_minnum_const_max_nnan_ninf(float %x) {
 
 define float @test_maxnum_const_max_nnan_ninf(float %x) {
 ; CHECK-LABEL: @test_maxnum_const_max_nnan_ninf(
-; CHECK-NEXT:    [[R:%.*]] = call nnan ninf float @llvm.maxnum.f32(float [[X:%.*]], float 0x47EFFFFFE0000000)
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0x47EFFFFFE0000000
 ;
   %r = call nnan ninf float @llvm.maxnum.f32(float %x, float 0x47efffffe0000000)
   ret float %r
@@ -443,8 +440,7 @@ define float @test_minimum_const_max_nnan_ninf(float %x) {
 
 define float @test_minnum_const_neg_max_nnan_ninf(float %x) {
 ; CHECK-LABEL: @test_minnum_const_neg_max_nnan_ninf(
-; CHECK-NEXT:    [[R:%.*]] = call nnan ninf float @llvm.minnum.f32(float [[X:%.*]], float 0xC7EFFFFFE0000000)
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0xC7EFFFFFE0000000
 ;
   %r = call nnan ninf float @llvm.minnum.f32(float %x, float 0xc7efffffe0000000)
   ret float %r


        


More information about the llvm-commits mailing list