[llvm] f74a334 - [ConstantFolding] add undef handling for fmin/fmax intrinsics

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 19 07:31:08 PDT 2020


Author: Sanjay Patel
Date: 2020-09-19T10:31:01-04:00
New Revision: f74a334fe35bcea08a48f76462782f0eafc6d564

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

LOG: [ConstantFolding] add undef handling for fmin/fmax intrinsics

The output here may not be optimal (yet), but it should be
consistent for commuted operands (it was not before) and
correct. We can do better by checking FMF and NaN if needed.

Code in InstSimplify generally assumes that we have already
folded code like this, so it was not handling 2 constant
inputs by commuting consistently.

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index aaab600bfc6b..0ddca5a09838 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2305,6 +2305,25 @@ static Constant *ConstantFoldScalarCall2(StringRef Name,
                                          const CallBase *Call) {
   assert(Operands.size() == 2 && "Wrong number of operands.");
 
+  if (Ty->isFloatingPointTy()) {
+    // TODO: We should have undef handling for all of the FP intrinsics that
+    //       are attempted to be folded in this function.
+    bool IsOp0Undef = isa<UndefValue>(Operands[0]);
+    bool IsOp1Undef = isa<UndefValue>(Operands[1]);
+    switch (IntrinsicID) {
+    case Intrinsic::maxnum:
+    case Intrinsic::minnum:
+    case Intrinsic::maximum:
+    case Intrinsic::minimum:
+      // If one argument is undef, return the other argument.
+      if (IsOp0Undef)
+        return Operands[1];
+      if (IsOp1Undef)
+        return Operands[0];
+      break;
+    }
+  }
+
   if (auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
     if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
       return nullptr;

diff  --git a/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll b/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll
index b77337a63a3b..fd139f0b880f 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/fp-undef.ll
@@ -540,7 +540,7 @@ define <2 x double> @frem_undef_op0_constant_vec(<2 x double> %x) {
 
 define <2 x double> @maximum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
 ; CHECK-LABEL: @maximum_nan_op0_vec_partial_undef_op1_undef(
-; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
+; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double undef>
 ;
   %r = call <2 x double> @llvm.maximum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
   ret <2 x double> %r
@@ -556,7 +556,7 @@ define <2 x double> @maximum_nan_op1_vec_partial_undef_op0_undef(<2 x double> %x
 
 define <2 x double> @minimum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
 ; CHECK-LABEL: @minimum_nan_op0_vec_partial_undef_op1_undef(
-; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
+; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double undef>
 ;
   %r = call <2 x double> @llvm.minimum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
   ret <2 x double> %r
@@ -572,7 +572,7 @@ define <2 x double> @minimum_nan_op1_vec_partial_undef_op0_undef(<2 x double> %x
 
 define <2 x double> @maxnum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
 ; CHECK-LABEL: @maxnum_nan_op0_vec_partial_undef_op1_undef(
-; CHECK-NEXT:    ret <2 x double> undef
+; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double undef>
 ;
   %r = call <2 x double> @llvm.maxnum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
   ret <2 x double> %r
@@ -588,7 +588,7 @@ define <2 x double> @maxnum_nan_op1_vec_partial_undef_op0_undef(<2 x double> %x)
 
 define <2 x double> @minnum_nan_op0_vec_partial_undef_op1_undef(<2 x double> %x) {
 ; CHECK-LABEL: @minnum_nan_op0_vec_partial_undef_op1_undef(
-; CHECK-NEXT:    ret <2 x double> undef
+; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double undef>
 ;
   %r = call <2 x double> @llvm.minnum.v2f64(<2 x double> <double 0x7ff8000000000000, double undef>, <2 x double> undef)
   ret <2 x double> %r


        


More information about the llvm-commits mailing list