GVN: propagate equalities for floating point compares
authorSanjay Patel <spatel@rotateright.com>
Mon, 12 Jan 2015 19:29:48 +0000 (19:29 +0000)
committerSanjay Patel <spatel@rotateright.com>
Mon, 12 Jan 2015 19:29:48 +0000 (19:29 +0000)
Allow optimizations based on FP comparison values in the same way
as integers.

This resolves PR17713:
http://llvm.org/bugs/show_bug.cgi?id=17713

Differential Revision: http://reviews.llvm.org/D6911

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

lib/Transforms/Scalar/GVN.cpp
test/Transforms/GVN/condprop.ll
test/Transforms/GVN/edge.ll

index 4ff442f98f2eb1f0ca32d38754616d1cc77dc002..7a5b0290aa17c9279231e468259a3d03642514ec 100644 (file)
@@ -2171,7 +2171,7 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS,
     // If we are propagating an equality like "(A == B)" == "true" then also
     // propagate the equality A == B.  When propagating a comparison such as
     // "(A >= B)" == "true", replace all instances of "A < B" with "false".
-    if (ICmpInst *Cmp = dyn_cast<ICmpInst>(LHS)) {
+    if (CmpInst *Cmp = dyn_cast<CmpInst>(LHS)) {
       Value *Op0 = Cmp->getOperand(0), *Op1 = Cmp->getOperand(1);
 
       // If "A == B" is known true, or "A != B" is known false, then replace
@@ -2180,6 +2180,11 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS,
           (isKnownFalse && Cmp->getPredicate() == CmpInst::ICMP_NE))
         Worklist.push_back(std::make_pair(Op0, Op1));
 
+      // Handle the floating point versions of equality comparisons too.
+      if ((isKnownTrue && Cmp->getPredicate() == CmpInst::FCMP_OEQ) ||
+          (isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE))
+        Worklist.push_back(std::make_pair(Op0, Op1));
+
       // If "A >= B" is known true, replace "A < B" with false everywhere.
       CmpInst::Predicate NotPred = Cmp->getInversePredicate();
       Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse);
index 708e4b23cb54e17a2ca9c186efcfc0e61a4e674e..845f88e15895b01dbbef7e65296a9420e10d2c50 100644 (file)
@@ -144,6 +144,22 @@ different:
   ret i1 %cmp3
 }
 
+; CHECK-LABEL: @test6_fp(
+define i1 @test6_fp(float %x, float %y) {
+  %cmp2 = fcmp une float %x, %y
+  %cmp = fcmp oeq float %x, %y
+  %cmp3 = fcmp oeq float  %x, %y
+  br i1 %cmp, label %same, label %different
+
+same:
+; CHECK: ret i1 false
+  ret i1 %cmp2
+
+different:
+; CHECK: ret i1 false
+  ret i1 %cmp3
+}
+
 ; CHECK-LABEL: @test7(
 define i1 @test7(i32 %x, i32 %y) {
   %cmp = icmp sgt i32 %x, %y
@@ -160,6 +176,22 @@ different:
   ret i1 %cmp3
 }
 
+; CHECK-LABEL: @test7_fp(
+define i1 @test7_fp(float %x, float %y) {
+  %cmp = fcmp ogt float %x, %y
+  br i1 %cmp, label %same, label %different
+
+same:
+  %cmp2 = fcmp ule float %x, %y
+; CHECK: ret i1 false
+  ret i1 %cmp2
+
+different:
+  %cmp3 = fcmp ogt float %x, %y
+; CHECK: ret i1 false
+  ret i1 %cmp3
+}
+
 ; CHECK-LABEL: @test8(
 define i1 @test8(i32 %x, i32 %y) {
   %cmp2 = icmp sle i32 %x, %y
@@ -176,6 +208,22 @@ different:
   ret i1 %cmp3
 }
 
+; CHECK-LABEL: @test8_fp(
+define i1 @test8_fp(float %x, float %y) {
+  %cmp2 = fcmp ule float %x, %y
+  %cmp = fcmp ogt float %x, %y
+  %cmp3 = fcmp ogt float %x, %y
+  br i1 %cmp, label %same, label %different
+
+same:
+; CHECK: ret i1 false
+  ret i1 %cmp2
+
+different:
+; CHECK: ret i1 false
+  ret i1 %cmp3
+}
+
 ; PR1768
 ; CHECK-LABEL: @test9(
 define i32 @test9(i32 %i, i32 %j) {
index 646e10c0cdfbe53489f89b29c268c4c47864f499..1dc285ec3d7cc76e2dd0745a4afb0cb4b460be0d 100644 (file)
@@ -58,3 +58,38 @@ bb2:
 ; CHECK: call void @g(i1 %y)
   ret void
 }
+
+define double @fcmp_oeq(double %x, double %y) {
+entry:
+  %cmp = fcmp oeq double %y, 2.0
+  br i1 %cmp, label %if, label %return
+
+if:
+  %div = fdiv double %x, %y
+  br label %return
+
+return:
+  %retval.0 = phi double [ %div, %if ], [ %x, %entry ]
+  ret double %retval.0
+
+; CHECK-LABEL: define double @fcmp_oeq(
+; CHECK: %div = fdiv double %x, 2.000000e+00
+}
+
+define double @fcmp_une(double %x, double %y) {
+entry:
+  %cmp = fcmp une double %y, 2.0
+  br i1 %cmp, label %return, label %else
+
+else:
+  %div = fdiv double %x, %y
+  br label %return
+
+return:
+  %retval.0 = phi double [ %div, %else ], [ %x, %entry ]
+  ret double %retval.0
+
+; CHECK-LABEL: define double @fcmp_une(
+; CHECK: %div = fdiv double %x, 2.000000e+00
+}
+