mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 02:36:06 +00:00
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225660 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
728315adf4
commit
2211d38267
@ -2171,7 +2171,7 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS,
|
|||||||
// If we are propagating an equality like "(A == B)" == "true" then also
|
// If we are propagating an equality like "(A == B)" == "true" then also
|
||||||
// propagate the equality A == B. When propagating a comparison such as
|
// propagate the equality A == B. When propagating a comparison such as
|
||||||
// "(A >= B)" == "true", replace all instances of "A < B" with "false".
|
// "(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);
|
Value *Op0 = Cmp->getOperand(0), *Op1 = Cmp->getOperand(1);
|
||||||
|
|
||||||
// If "A == B" is known true, or "A != B" is known false, then replace
|
// 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))
|
(isKnownFalse && Cmp->getPredicate() == CmpInst::ICMP_NE))
|
||||||
Worklist.push_back(std::make_pair(Op0, Op1));
|
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.
|
// If "A >= B" is known true, replace "A < B" with false everywhere.
|
||||||
CmpInst::Predicate NotPred = Cmp->getInversePredicate();
|
CmpInst::Predicate NotPred = Cmp->getInversePredicate();
|
||||||
Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse);
|
Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse);
|
||||||
|
@ -144,6 +144,22 @@ different:
|
|||||||
ret i1 %cmp3
|
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(
|
; CHECK-LABEL: @test7(
|
||||||
define i1 @test7(i32 %x, i32 %y) {
|
define i1 @test7(i32 %x, i32 %y) {
|
||||||
%cmp = icmp sgt i32 %x, %y
|
%cmp = icmp sgt i32 %x, %y
|
||||||
@ -160,6 +176,22 @@ different:
|
|||||||
ret i1 %cmp3
|
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(
|
; CHECK-LABEL: @test8(
|
||||||
define i1 @test8(i32 %x, i32 %y) {
|
define i1 @test8(i32 %x, i32 %y) {
|
||||||
%cmp2 = icmp sle i32 %x, %y
|
%cmp2 = icmp sle i32 %x, %y
|
||||||
@ -176,6 +208,22 @@ different:
|
|||||||
ret i1 %cmp3
|
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
|
; PR1768
|
||||||
; CHECK-LABEL: @test9(
|
; CHECK-LABEL: @test9(
|
||||||
define i32 @test9(i32 %i, i32 %j) {
|
define i32 @test9(i32 %i, i32 %j) {
|
||||||
|
@ -58,3 +58,38 @@ bb2:
|
|||||||
; CHECK: call void @g(i1 %y)
|
; CHECK: call void @g(i1 %y)
|
||||||
ret void
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user