diff options
author | Chris Lattner <sabre@nondot.org> | 2008-08-06 05:13:06 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-08-06 05:13:06 +0000 |
commit | 5af5f463e1b95e2af8d69591d07282427c2dc6a4 (patch) | |
tree | 88716c0b14c225f7e1537da7e37cfb4eba0b4b3d | |
parent | b30591ec646b5f53c1163bf9bd74091248598589 (diff) |
Zap sitofp/fptoui pairs. In all cases when the sign difference
matters, the result is undefined anyway.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54396 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 46 | ||||
-rw-r--r-- | test/Transforms/InstCombine/sitofp.ll | 14 |
2 files changed, 43 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index fbd0d20071..44083bc2d0 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -7750,27 +7750,41 @@ Instruction *InstCombiner::visitFPExt(CastInst &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 */ - SrcI->getType()->getFPMantissaWidth()) - return ReplaceInstUsesWith(FI, SrcI->getOperand(0)); + Instruction *OpI = dyn_cast<Instruction>(FI.getOperand(0)); + if (OpI == 0) + return commonCastTransforms(FI); + + // fptoui(uitofp(X)) --> X + // fptoui(sitofp(X)) --> X + // This is safe 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. This is also safe for sitofp case, because any negative + // 'X' value would cause an undefined result for the fptoui. + if ((isa<UIToFPInst>(OpI) || isa<SIToFPInst>(OpI)) && + OpI->getOperand(0)->getType() == FI.getType() && + (int)FI.getType()->getPrimitiveSizeInBits() < /*extra bit for sign */ + OpI->getType()->getFPMantissaWidth()) + return ReplaceInstUsesWith(FI, OpI->getOperand(0)); return commonCastTransforms(FI); } 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() <= - SrcI->getType()->getFPMantissaWidth()) - return ReplaceInstUsesWith(FI, SrcI->getOperand(0)); + Instruction *OpI = dyn_cast<Instruction>(FI.getOperand(0)); + if (OpI == 0) + return commonCastTransforms(FI); + + // fptosi(sitofp(X)) --> X + // fptosi(uitofp(X)) --> X + // This is safe 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. This is also safe for sitofp case, because any negative + // 'X' value would cause an undefined result for the fptoui. + if ((isa<UIToFPInst>(OpI) || isa<SIToFPInst>(OpI)) && + OpI->getOperand(0)->getType() == FI.getType() && + (int)FI.getType()->getPrimitiveSizeInBits() <= + OpI->getType()->getFPMantissaWidth()) + return ReplaceInstUsesWith(FI, OpI->getOperand(0)); return commonCastTransforms(FI); } diff --git a/test/Transforms/InstCombine/sitofp.ll b/test/Transforms/InstCombine/sitofp.ll index 73dd23bc43..c26c351a74 100644 --- a/test/Transforms/InstCombine/sitofp.ll +++ b/test/Transforms/InstCombine/sitofp.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep sitofp +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep itofp define i1 @test1(i8 %A) { %B = sitofp i8 %A to double @@ -41,3 +41,15 @@ define i32 @test6(i32 %A) { ret i32 %G } +define i32 @test7(i32 %a) nounwind { + %b = sitofp i32 %a to double ; <double> [#uses=1] + %c = fptoui double %b to i32 ; <i32> [#uses=1] + ret i32 %c +} + +define i32 @test8(i32 %a) nounwind { + %b = uitofp i32 %a to double ; <double> [#uses=1] + %c = fptosi double %b to i32 ; <i32> [#uses=1] + ret i32 %c +} + |