[InstSimplify] Fold away ord/uno fcmps when nnan is present.
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 10 Jul 2015 14:02:02 +0000 (14:02 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 10 Jul 2015 14:02:02 +0000 (14:02 +0000)
This is important to fold away the slow case of complex multiplies
emitted by clang.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241911 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/InstructionSimplify.h
lib/Analysis/InstructionSimplify.cpp
lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstSimplify/floating-point-compare.ll

index 706bd8000d3ab1aeb7168563db112e78e01771bc..65654b1ba34271e6a9f0b4438b2deeaab435d120 100644 (file)
@@ -212,7 +212,7 @@ namespace llvm {
   /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
   /// fold the result.  If not, this returns null.
   Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
-                          const DataLayout &DL,
+                          FastMathFlags FMF, const DataLayout &DL,
                           const TargetLibraryInfo *TLI = nullptr,
                           const DominatorTree *DT = nullptr,
                           AssumptionCache *AC = nullptr,
index 12e406bb1a2d52398107d6c828ca7cd26070e890..ab5cd01ab634744a976aa8f0b7d69050703e04f5 100644 (file)
@@ -3046,7 +3046,8 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
 /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
 /// fold the result.  If not, this returns null.
 static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
-                               const Query &Q, unsigned MaxRecurse) {
+                               FastMathFlags FMF, const Query &Q,
+                               unsigned MaxRecurse) {
   CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate;
   assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!");
 
@@ -3065,6 +3066,14 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
   if (Pred == FCmpInst::FCMP_TRUE)
     return ConstantInt::get(GetCompareTy(LHS), 1);
 
+  // UNO/ORD predicates can be trivially folded if NaNs are ignored.
+  if (FMF.noNaNs()) {
+    if (Pred == FCmpInst::FCMP_UNO)
+      return ConstantInt::get(GetCompareTy(LHS), 0);
+    if (Pred == FCmpInst::FCMP_ORD)
+      return ConstantInt::get(GetCompareTy(LHS), 1);
+  }
+
   // fcmp pred x, undef  and  fcmp pred undef, x
   // fold to true if unordered, false if ordered
   if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS)) {
@@ -3151,12 +3160,12 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
 }
 
 Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
-                              const DataLayout &DL,
+                              FastMathFlags FMF, const DataLayout &DL,
                               const TargetLibraryInfo *TLI,
                               const DominatorTree *DT, AssumptionCache *AC,
                               const Instruction *CxtI) {
-  return ::SimplifyFCmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
-                            RecursionLimit);
+  return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF,
+                            Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
 }
 
 /// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
@@ -3670,7 +3679,7 @@ static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
                               const Query &Q, unsigned MaxRecurse) {
   if (CmpInst::isIntPredicate((CmpInst::Predicate)Predicate))
     return SimplifyICmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
-  return SimplifyFCmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
+  return SimplifyFCmpInst(Predicate, LHS, RHS, FastMathFlags(), Q, MaxRecurse);
 }
 
 Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
@@ -3900,9 +3909,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
                          I->getOperand(1), DL, TLI, DT, AC, I);
     break;
   case Instruction::FCmp:
-    Result =
-        SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(), I->getOperand(0),
-                         I->getOperand(1), DL, TLI, DT, AC, I);
+    Result = SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
+                              I->getOperand(0), I->getOperand(1),
+                              I->getFastMathFlags(), DL, TLI, DT, AC, I);
     break;
   case Instruction::Select:
     Result = SimplifySelectInst(I->getOperand(0), I->getOperand(1),
index 010b7b57c3e7e56d931e2b78f4f20ddc10236842..0bd6fd2f226d991cc521669c1ac73c443da7157c 100644 (file)
@@ -3928,8 +3928,8 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
 
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
-  if (Value *V =
-          SimplifyFCmpInst(I.getPredicate(), Op0, Op1, DL, TLI, DT, AC, &I))
+  if (Value *V = SimplifyFCmpInst(I.getPredicate(), Op0, Op1,
+                                  I.getFastMathFlags(), DL, TLI, DT, AC, &I))
     return ReplaceInstUsesWith(I, V);
 
   // Simplify 'fcmp pred X, X'
index af48d062b4f6422463c67140d78ab8ba262b3b76..8174f5834533232209065fc01c76ffebfb7f3ead 100644 (file)
@@ -58,3 +58,18 @@ define i1 @orderedLessZeroPowi(double,double) {
   ret i1 %olt
 }
 
+define i1 @nonans1(double %in1, double %in2) {
+  %cmp = fcmp nnan uno double %in1, %in2
+  ret i1 %cmp
+
+; CHECK-LABEL: @nonans1
+; CHECK-NEXT: ret i1 false
+}
+
+define i1 @nonans2(double %in1, double %in2) {
+  %cmp = fcmp nnan ord double %in1, %in2
+  ret i1 %cmp
+
+; CHECK-LABEL: @nonans2
+; CHECK-NEXT: ret i1 true
+}