diff options
| -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 fbd0d20..44083bc 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 73dd23b..c26c351 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 +} + |
