Just because we have determined that an (fcmp | fcmp) is true for A < B,
authorOwen Anderson <resistor@mac.com>
Fri, 21 Jan 2011 19:39:42 +0000 (19:39 +0000)
committerOwen Anderson <resistor@mac.com>
Fri, 21 Jan 2011 19:39:42 +0000 (19:39 +0000)
A == B, and A > B, does not mean we can fold it to true.  We still need to
check for A ? B (A unordered B).

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

lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/or-fcmp.ll

index a27a566341f30bc61e02ae76a25b1c7e251a3859..e6318e9bc80cbb3f8279a53fef59d56cef68ef64 100644 (file)
@@ -172,7 +172,9 @@ static Value *getFCmpValue(bool isordered, unsigned code,
   case 4: Pred = isordered ? FCmpInst::FCMP_OLT : FCmpInst::FCMP_ULT; break;
   case 5: Pred = isordered ? FCmpInst::FCMP_ONE : FCmpInst::FCMP_UNE; break;
   case 6: Pred = isordered ? FCmpInst::FCMP_OLE : FCmpInst::FCMP_ULE; break;
-  case 7: return ConstantInt::getTrue(LHS->getContext());
+  case 7: 
+    if (!isordered) return ConstantInt::getTrue(LHS->getContext());
+    Pred = FCmpInst::FCMP_ORD; break;
   }
   return Builder->CreateFCmp(Pred, LHS, RHS);
 }
index 9692bfcc597030cc368205414df7c7d92ea823f8..09a3c994d93e72ff7ca8cf374a346d5ad2526834 100644 (file)
@@ -1,34 +1,58 @@
-; RUN: opt < %s -instcombine -S | grep fcmp | count 3
-; RUN: opt < %s -instcombine -S | grep ret | grep 1
+; RUN: opt < %s -instcombine -S | FileCheck %s
 
+; CHECK: @t1
 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
+; CHECK-NOT: fcmp uno
+; CHECK: fcmp ueq
        %retval = zext i1 %c to i8
        ret i8 %retval
 }
 
+; CHECK: @t2
 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]
+; CHECK-NOT: fcmp olt
+; CHECK-NOT: fcmp oeq
+; CHECK: fcmp ole
        %c = or i1 %a, %b
        %retval = zext i1 %c to i8
        ret i8 %retval
 }
 
+; CHECK: @t3
 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
+; CHECK: ret i8 1
        ret i8 %retval
 }
 
+; CHECK: @t4
 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
+; CHECK-NOT: fcmp ult
+; CHECK-NOT: fcmp ugt
+; CHECK: fcmp une
+       %retval = zext i1 %c to i8
+       ret i8 %retval
+}
+
+; CHECK: @t5
+define zeroext i8 @t5(float %x, float %y) nounwind {
+       %a = fcmp olt float %x, %y             ; <i1> [#uses=1]
+       %b = fcmp oge float %x, %y               ; <i1> [#uses=1]
+       %c = or i1 %a, %b
+; CHECK-NOT: fcmp olt
+; CHECK-NOT: fcmp oge
+; CHECK: fcmp ord
        %retval = zext i1 %c to i8
        ret i8 %retval
 }