[llvm-commits] [llvm] r43289 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and2.ll test/Transforms/InstCombine/or2.ll

Chris Lattner sabre at nondot.org
Tue Oct 23 22:38:08 PDT 2007


Author: lattner
Date: Wed Oct 24 00:38:08 2007
New Revision: 43289

URL: http://llvm.org/viewvc/llvm-project?rev=43289&view=rev
Log:
Implement a couple of foldings for ordered and unordered comparisons,
implementing cases related to PR1738.

Added:
    llvm/trunk/test/Transforms/InstCombine/and2.ll
    llvm/trunk/test/Transforms/InstCombine/or2.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=43289&r1=43288&r2=43289&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Oct 24 00:38:08 2007
@@ -3628,6 +3628,24 @@
       }
   }
 
+  // (fcmp ord x, c) & (fcmp ord y, c)  -> (fcmp ord x, y)
+  if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) {
+    if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1))) {
+      if (LHS->getPredicate() == FCmpInst::FCMP_ORD &&
+          RHS->getPredicate() == FCmpInst::FCMP_ORD)
+        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
+            // false.
+            if (LHSC->getValueAPF().getCategory() == APFloat::fcNaN ||
+                RHSC->getValueAPF().getCategory() == APFloat::fcNaN)
+              return ReplaceInstUsesWith(I, ConstantInt::getFalse());
+            return new FCmpInst(FCmpInst::FCMP_ORD, LHS->getOperand(0),
+                                RHS->getOperand(0));
+          }
+    }
+  }
+      
   return Changed ? &I : 0;
 }
 
@@ -4074,7 +4092,7 @@
   }
     
   // fold (or (cast A), (cast B)) -> (cast (or A, B))
-  if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
     if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
       if (Op0C->getOpcode() == Op1C->getOpcode()) {// same cast kind ?
         const Type *SrcTy = Op0C->getOperand(0)->getType();
@@ -4091,7 +4109,29 @@
           return CastInst::create(Op0C->getOpcode(), NewOp, I.getType());
         }
       }
-      
+  }
+  
+    
+  // (fcmp uno x, c) | (fcmp uno y, c)  -> (fcmp uno x, y)
+  if (FCmpInst *LHS = dyn_cast<FCmpInst>(I.getOperand(0))) {
+    if (FCmpInst *RHS = dyn_cast<FCmpInst>(I.getOperand(1))) {
+      if (LHS->getPredicate() == FCmpInst::FCMP_UNO &&
+          RHS->getPredicate() == FCmpInst::FCMP_UNO)
+        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
+            // true.
+            if (LHSC->getValueAPF().getCategory() == APFloat::fcNaN ||
+                RHSC->getValueAPF().getCategory() == APFloat::fcNaN)
+              return ReplaceInstUsesWith(I, ConstantInt::getTrue());
+            
+            // Otherwise, no need to compare the two constants, compare the
+            // rest.
+            return new FCmpInst(FCmpInst::FCMP_UNO, LHS->getOperand(0),
+                                RHS->getOperand(0));
+          }
+    }
+  }
 
   return Changed ? &I : 0;
 }
@@ -4341,7 +4381,7 @@
       return R;
 
   // fold (xor (cast A), (cast B)) -> (cast (xor A, B))
-  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) 
+  if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
     if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
       if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind?
         const Type *SrcTy = Op0C->getOperand(0)->getType();
@@ -4358,7 +4398,7 @@
           return CastInst::create(Op0C->getOpcode(), NewOp, I.getType());
         }
       }
-
+  }
   return Changed ? &I : 0;
 }
 

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

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/and2.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/and2.ll Wed Oct 24 00:38:08 2007
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep and
+
+
+; PR1738
+define i1 @test1(double %X, double %Y) {
+        %tmp9 = fcmp ord double %X, 0.000000e+00
+        %tmp13 = fcmp ord double %Y, 0.000000e+00
+        %bothcond = and i1 %tmp13, %tmp9
+        ret i1 %bothcond
+}
+
+

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

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/or2.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/or2.ll Wed Oct 24 00:38:08 2007
@@ -0,0 +1,12 @@
+; This test makes sure that these instructions are properly eliminated.
+;
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v xor | not grep {or }
+
+; PR1738
+define i1 @test1(double %X, double %Y) {
+        %tmp9 = fcmp uno double %X, 0.000000e+00                ; <i1> [#uses=1]
+        %tmp13 = fcmp uno double %Y, 0.000000e+00               ; <i1> [#uses=1]
+        %bothcond = or i1 %tmp13, %tmp9         ; <i1> [#uses=1]
+        ret i1 %bothcond
+}
+





More information about the llvm-commits mailing list