aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-05-19 20:25:04 +0000
committerChris Lattner <sabre@nondot.org>2008-05-19 20:25:04 +0000
commitdeef1a72f6f44ba143922414b1490a5bb03d79a0 (patch)
tree96910ee44d3414fabf6b386aea966907128f8224
parente6b62d988e02bb7d759214e3fd90e01cbe1a570b (diff)
downloadexternal_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.cpp36
-rw-r--r--test/Transforms/InstCombine/sitofp.ll8
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
+}
+