[llvm] r225660 - GVN: propagate equalities for floating point compares
Sanjay Patel
spatel at rotateright.com
Mon Jan 12 11:29:48 PST 2015
Author: spatel
Date: Mon Jan 12 13:29:48 2015
New Revision: 225660
URL: http://llvm.org/viewvc/llvm-project?rev=225660&view=rev
Log:
GVN: propagate equalities for floating point compares
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
Modified:
llvm/trunk/lib/Transforms/Scalar/GVN.cpp
llvm/trunk/test/Transforms/GVN/condprop.ll
llvm/trunk/test/Transforms/GVN/edge.ll
Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=225660&r1=225659&r2=225660&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Jan 12 13:29:48 2015
@@ -2171,7 +2171,7 @@ bool GVN::propagateEquality(Value *LHS,
// 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,
(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);
Modified: llvm/trunk/test/Transforms/GVN/condprop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/condprop.ll?rev=225660&r1=225659&r2=225660&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GVN/condprop.ll (original)
+++ llvm/trunk/test/Transforms/GVN/condprop.ll Mon Jan 12 13:29:48 2015
@@ -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
@@ -168,6 +200,22 @@ define i1 @test8(i32 %x, i32 %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: @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
Modified: llvm/trunk/test/Transforms/GVN/edge.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/edge.ll?rev=225660&r1=225659&r2=225660&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GVN/edge.ll (original)
+++ llvm/trunk/test/Transforms/GVN/edge.ll Mon Jan 12 13:29:48 2015
@@ -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
+}
+
More information about the llvm-commits
mailing list