mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-21 19:32:16 +00:00
InstCombine: Shrink "fcmp (fpext x), C" to "fcmp x, C" if C can be losslessly converted to the type of x.
Fixes PR9592. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128625 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd0274ca18
commit
b194bdc03b
@ -2762,6 +2762,40 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
|
|||||||
if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
|
if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
|
||||||
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
|
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
|
||||||
switch (LHSI->getOpcode()) {
|
switch (LHSI->getOpcode()) {
|
||||||
|
case Instruction::FPExt: {
|
||||||
|
// fcmp (fpext x), C -> fcmp x, (fptrunc C) if fptrunc is lossless
|
||||||
|
FPExtInst *LHSExt = cast<FPExtInst>(LHSI);
|
||||||
|
ConstantFP *RHSF = dyn_cast<ConstantFP>(RHSC);
|
||||||
|
if (!RHSF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const fltSemantics *Sem;
|
||||||
|
// FIXME: This shouldn't be here.
|
||||||
|
if (LHSExt->getSrcTy()->isFloatTy())
|
||||||
|
Sem = &APFloat::IEEEsingle;
|
||||||
|
else if (LHSExt->getSrcTy()->isDoubleTy())
|
||||||
|
Sem = &APFloat::IEEEdouble;
|
||||||
|
else if (LHSExt->getSrcTy()->isFP128Ty())
|
||||||
|
Sem = &APFloat::IEEEquad;
|
||||||
|
else if (LHSExt->getSrcTy()->isX86_FP80Ty())
|
||||||
|
Sem = &APFloat::x87DoubleExtended;
|
||||||
|
else if (LHSExt->getSrcTy()->isPPC_FP128Ty())
|
||||||
|
Sem = &APFloat::PPCDoubleDouble;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
bool Lossy;
|
||||||
|
APFloat F = RHSF->getValueAPF();
|
||||||
|
F.convert(*Sem, APFloat::rmNearestTiesToEven, &Lossy);
|
||||||
|
|
||||||
|
// Avoid lossy conversions and denormals.
|
||||||
|
if (!Lossy &&
|
||||||
|
F.compare(APFloat::getSmallestNormalized(*Sem)) !=
|
||||||
|
APFloat::cmpLessThan)
|
||||||
|
return new FCmpInst(I.getPredicate(), LHSExt->getOperand(0),
|
||||||
|
ConstantFP::get(RHSC->getContext(), F));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Instruction::PHI:
|
case Instruction::PHI:
|
||||||
// Only fold fcmp into the PHI if the phi and fcmp are in the same
|
// Only fold fcmp into the PHI if the phi and fcmp are in the same
|
||||||
// block. If in the same block, we're encouraging jump threading. If
|
// block. If in the same block, we're encouraging jump threading. If
|
||||||
|
@ -9,3 +9,26 @@ define i1 @test1(float %x, float %y) nounwind {
|
|||||||
; CHECK-NEXT: fcmp ogt float %x, %y
|
; CHECK-NEXT: fcmp ogt float %x, %y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i1 @test2(float %a) nounwind {
|
||||||
|
%ext = fpext float %a to double
|
||||||
|
%cmp = fcmp ogt double %ext, 1.000000e+00
|
||||||
|
ret i1 %cmp
|
||||||
|
; CHECK: @test2
|
||||||
|
; CHECK-NEXT: fcmp ogt float %a, 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
define i1 @test3(float %a) nounwind {
|
||||||
|
%ext = fpext float %a to double
|
||||||
|
%cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float.
|
||||||
|
ret i1 %cmp
|
||||||
|
; CHECK: @test3
|
||||||
|
; CHECK-NEXT: fpext float %a to double
|
||||||
|
}
|
||||||
|
|
||||||
|
define i1 @test4(float %a) nounwind {
|
||||||
|
%ext = fpext float %a to double
|
||||||
|
%cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float.
|
||||||
|
ret i1 %cmp
|
||||||
|
; CHECK: @test4
|
||||||
|
; CHECK-NEXT: fpext float %a to double
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user