[llvm-commits] [llvm] r57515 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or-fcmp.ll

Evan Cheng evan.cheng at apple.com
Tue Oct 14 11:44:09 PDT 2008


Author: evancheng
Date: Tue Oct 14 13:44:08 2008
New Revision: 57515

URL: http://llvm.org/viewvc/llvm-project?rev=57515&view=rev
Log:
Combine (fcmp cc0 x, y) | (fcmp cc1 x, y) into a single fcmp when possible.

Added:
    llvm/trunk/test/Transforms/InstCombine/or-fcmp.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=57515&r1=57514&r2=57515&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Oct 14 13:44:08 2008
@@ -3136,6 +3136,7 @@
   case FCmpInst::FCMP_UNE:                   return 5;  // 101
   case FCmpInst::FCMP_OLE: isOrdered = true; return 6;  // 110
   case FCmpInst::FCMP_ULE:                   return 6;  // 110
+    // True -> 7
   default:
     // Not expecting FCMP_FALSE and FCMP_TRUE;
     assert(0 && "Unexpected FCmp predicate!");
@@ -3219,6 +3220,7 @@
       return new FCmpInst(FCmpInst::FCMP_OLE, LHS, RHS);
     else
       return new FCmpInst(FCmpInst::FCMP_ULE, LHS, RHS);
+  case  7: return ConstantInt::getTrue();
   }
 }
 
@@ -4555,7 +4557,7 @@
     if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1))) {
       if (LHS->getPredicate() == FCmpInst::FCMP_UNO &&
           RHS->getPredicate() == FCmpInst::FCMP_UNO && 
-          LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType())
+          LHS->getOperand(0)->getType() == RHS->getOperand(0)->getType()) {
         if (ConstantFP *LHSC = dyn_cast<ConstantFP>(LHS->getOperand(1)))
           if (ConstantFP *RHSC = dyn_cast<ConstantFP>(RHS->getOperand(1))) {
             // If either of the constants are nans, then the whole thing returns
@@ -4568,6 +4570,44 @@
             return new FCmpInst(FCmpInst::FCMP_UNO, LHS->getOperand(0),
                                 RHS->getOperand(0));
           }
+      } else {
+        Value *Op0LHS, *Op0RHS, *Op1LHS, *Op1RHS;
+        FCmpInst::Predicate Op0CC, Op1CC;
+        if (match(Op0, m_FCmp(Op0CC, m_Value(Op0LHS), m_Value(Op0RHS))) &&
+            match(Op1, m_FCmp(Op1CC, m_Value(Op1LHS), m_Value(Op1RHS)))) {
+          if (Op0LHS == Op1RHS && Op0RHS == Op1LHS) {
+            // Swap RHS operands to match LHS.
+            Op1CC = FCmpInst::getSwappedPredicate(Op1CC);
+            std::swap(Op1LHS, Op1RHS);
+          }
+          if (Op0LHS == Op1LHS && Op0RHS == Op1RHS) {
+            // Simplify (fcmp cc0 x, y) | (fcmp cc1 x, y).
+            if (Op0CC == Op1CC)
+              return new FCmpInst((FCmpInst::Predicate)Op0CC, Op0LHS, Op0RHS);
+            else if (Op0CC == FCmpInst::FCMP_TRUE ||
+                     Op1CC == FCmpInst::FCMP_TRUE)
+              return ReplaceInstUsesWith(I, ConstantInt::getTrue());
+            else if (Op0CC == FCmpInst::FCMP_FALSE)
+              return ReplaceInstUsesWith(I, Op1);
+            else if (Op1CC == FCmpInst::FCMP_FALSE)
+              return ReplaceInstUsesWith(I, Op0);
+            bool Op0Ordered;
+            bool Op1Ordered;
+            unsigned Op0Pred = getFCmpCode(Op0CC, Op0Ordered);
+            unsigned Op1Pred = getFCmpCode(Op1CC, Op1Ordered);
+            if (Op0Ordered == Op1Ordered) {
+              // If both are ordered or unordered, return a new fcmp with
+              // or'ed predicates.
+              Value *RV = getFCmpValue(Op0Ordered, Op0Pred|Op1Pred,
+                                       Op0LHS, Op0RHS);
+              if (Instruction *I = dyn_cast<Instruction>(RV))
+                return I;
+              // Otherwise, it's a constant boolean value...
+              return ReplaceInstUsesWith(I, RV);
+            }
+          }
+        }
+      }
     }
   }
 

Added: llvm/trunk/test/Transforms/InstCombine/or-fcmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/or-fcmp.ll?rev=57515&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/or-fcmp.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/or-fcmp.ll Tue Oct 14 13:44:08 2008
@@ -0,0 +1,34 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep fcmp | count 3
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep ret | grep 1
+
+define zeroext i8 @t1(float %x, float %y) nounwind {
+       %a = fcmp ueq float %x, %y             ; <i1> [#uses=1]
+       %b = fcmp uno float %x, %y               ; <i1> [#uses=1]
+       %c = or i1 %a, %b
+       %retval = zext i1 %c to i8
+       ret i8 %retval
+}
+
+define zeroext i8 @t2(float %x, float %y) nounwind {
+       %a = fcmp olt float %x, %y             ; <i1> [#uses=1]
+       %b = fcmp oeq float %x, %y               ; <i1> [#uses=1]
+       %c = or i1 %a, %b
+       %retval = zext i1 %c to i8
+       ret i8 %retval
+}
+
+define zeroext i8 @t3(float %x, float %y) nounwind {
+       %a = fcmp ult float %x, %y             ; <i1> [#uses=1]
+       %b = fcmp uge float %x, %y               ; <i1> [#uses=1]
+       %c = or i1 %a, %b
+       %retval = zext i1 %c to i8
+       ret i8 %retval
+}
+
+define zeroext i8 @t4(float %x, float %y) nounwind {
+       %a = fcmp ult float %x, %y             ; <i1> [#uses=1]
+       %b = fcmp ugt float %x, %y               ; <i1> [#uses=1]
+       %c = or i1 %a, %b
+       %retval = zext i1 %c to i8
+       ret i8 %retval
+}





More information about the llvm-commits mailing list