diff options
author | Chris Lattner <sabre@nondot.org> | 2008-05-19 20:25:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-05-19 20:25:04 +0000 |
commit | deef1a72f6f44ba143922414b1490a5bb03d79a0 (patch) | |
tree | 96910ee44d3414fabf6b386aea966907128f8224 | |
parent | e6b62d988e02bb7d759214e3fd90e01cbe1a570b (diff) | |
download | external_llvm-deef1a72f6f44ba143922414b1490a5bb03d79a0.zip external_llvm-deef1a72f6f44ba143922414b1490a5bb03d79a0.tar.gz external_llvm-deef1a72f6f44ba143922414b1490a5bb03d79a0.tar.bz2 |
convert fptosi(sitofp x) -> x if the fp value has enough bits in its mantissa
to accurately represent the integer. This triggers 9 times in 471.omnetpp,
though 8 of those seem to be inlined from the same place.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51271 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 36 | ||||
-rw-r--r-- | test/Transforms/InstCombine/sitofp.ll | 8 |
2 files changed, 35 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index fff6dba..46dba39 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -208,8 +208,8 @@ namespace { Instruction *visitSExt(SExtInst &CI); Instruction *visitFPTrunc(FPTruncInst &CI); Instruction *visitFPExt(CastInst &CI); - Instruction *visitFPToUI(CastInst &CI); - Instruction *visitFPToSI(CastInst &CI); + Instruction *visitFPToUI(FPToUIInst &FI); + Instruction *visitFPToSI(FPToSIInst &FI); Instruction *visitUIToFP(CastInst &CI); Instruction *visitSIToFP(CastInst &CI); Instruction *visitPtrToInt(CastInst &CI); @@ -2439,9 +2439,9 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { } while (Size >= 1); // FIXME: This shouldn't be necessary. When the backends can handle types - // with funny bit widths then this whole cascade of if statements should - // be removed. It is just here to get the size of the "middle" type back - // up to something that the back ends can handle. + // with funny bit widths then this switch statement should be removed. It + // is just here to get the size of the "middle" type back up to something + // that the back ends can handle. const Type *MiddleType = 0; switch (Size) { default: break; @@ -7995,12 +7995,30 @@ Instruction *InstCombiner::visitFPExt(CastInst &CI) { return commonCastTransforms(CI); } -Instruction *InstCombiner::visitFPToUI(CastInst &CI) { - return commonCastTransforms(CI); +Instruction *InstCombiner::visitFPToUI(FPToUIInst &FI) { + // fptoui(uitofp(X)) --> X if the intermediate type has enough bits in its + // mantissa to accurately represent all values of X. For example, do not + // do this with i64->float->i64. + if (UIToFPInst *SrcI = dyn_cast<UIToFPInst>(FI.getOperand(0))) + if (SrcI->getOperand(0)->getType() == FI.getType() && + (int)FI.getType()->getPrimitiveSizeInBits() < /*extra bit for sign */ + GetFPMantissaWidth(SrcI->getType())) + return ReplaceInstUsesWith(FI, SrcI->getOperand(0)); + + return commonCastTransforms(FI); } -Instruction *InstCombiner::visitFPToSI(CastInst &CI) { - return commonCastTransforms(CI); +Instruction *InstCombiner::visitFPToSI(FPToSIInst &FI) { + // fptosi(sitofp(X)) --> X if the intermediate type has enough bits in its + // mantissa to accurately represent all values of X. For example, do not + // do this with i64->float->i64. + if (SIToFPInst *SrcI = dyn_cast<SIToFPInst>(FI.getOperand(0))) + if (SrcI->getOperand(0)->getType() == FI.getType() && + (int)FI.getType()->getPrimitiveSizeInBits() <= + GetFPMantissaWidth(SrcI->getType())) + return ReplaceInstUsesWith(FI, SrcI->getOperand(0)); + + return commonCastTransforms(FI); } Instruction *InstCombiner::visitUIToFP(CastInst &CI) { diff --git a/test/Transforms/InstCombine/sitofp.ll b/test/Transforms/InstCombine/sitofp.ll index fd06dea..f7b1c91 100644 --- a/test/Transforms/InstCombine/sitofp.ll +++ b/test/Transforms/InstCombine/sitofp.ll @@ -23,3 +23,11 @@ define i1 @test4(i8 %A) { ret i1 %C ; A != 127 } +define i32 @test5(i32 %A) { + %B = sitofp i32 %A to double + %C = fptosi double %B to i32 + %D = uitofp i32 %C to double + %E = fptoui double %D to i32 + ret i32 %E +} + |