diff options
author | zhongyunde <zhongyunde@huawei.com> | 2022-07-08 17:03:17 +0800 |
---|---|---|
committer | zhongyunde <zhongyunde@huawei.com> | 2022-07-08 17:07:20 +0800 |
commit | 716e1b856aa38ef1d988af73413e7e4aadad2ffa (patch) | |
tree | 418f0c07984eda26f4f8f92c0e82422deeed6697 /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | |
parent | 7b9a3b9d6d98184d3e20c03fceefaac6dc0c3580 (diff) | |
download | llvm-716e1b856aa38ef1d988af73413e7e4aadad2ffa.zip llvm-716e1b856aa38ef1d988af73413e7e4aadad2ffa.tar.gz llvm-716e1b856aa38ef1d988af73413e7e4aadad2ffa.tar.bz2 |
[IndVars] Eliminate redundant type cast between integer and float
Recompute the range: match for fptosi of sitofp, and then query the range of the input to the sitofp
according the comment on D129140.
Fixes https://github.com/llvm/llvm-project/issues/55505.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D129191
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp index dbef1ff..64546ae 100644 --- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -79,6 +79,7 @@ namespace { bool eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand); bool replaceIVUserWithLoopInvariant(Instruction *UseInst); + bool replaceFloatIVWithIntegerIV(Instruction *UseInst); bool eliminateOverflowIntrinsic(WithOverflowInst *WO); bool eliminateSaturatingIntrinsic(SaturatingInst *SI); @@ -673,6 +674,35 @@ bool SimplifyIndvar::replaceIVUserWithLoopInvariant(Instruction *I) { return true; } +/// Eliminate redundant type cast between integer and float. +bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) { + if (UseInst->getOpcode() != CastInst::SIToFP) + return false; + + Value *IVOperand = UseInst->getOperand(0); + // Get the symbolic expression for this instruction. + ConstantRange IVRange = SE->getSignedRange(SE->getSCEV(IVOperand)); + unsigned DestNumSigBits = UseInst->getType()->getFPMantissaWidth(); + if (IVRange.getActiveBits() <= DestNumSigBits) { + for (User *U : UseInst->users()) { + // Match for fptosi of sitofp and with same type. + auto *CI = dyn_cast<FPToSIInst>(U); + if (!CI || IVOperand->getType() != CI->getType()) + continue; + + CI->replaceAllUsesWith(IVOperand); + DeadInsts.push_back(CI); + LLVM_DEBUG(dbgs() << "INDVARS: Replace IV user: " << *CI + << " with: " << *IVOperand << '\n'); + + ++NumFoldedUser; + Changed = true; + } + } + + return Changed; +} + /// Eliminate any operation that SCEV can prove is an identity function. bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand) { @@ -896,6 +926,13 @@ void SimplifyIndvar::simplifyUsers(PHINode *CurrIV, IVVisitor *V) { } } + // Try to use integer induction for FPToSI of float induction directly. + if (replaceFloatIVWithIntegerIV(UseInst)) { + // Re-queue the potentially new direct uses of IVOperand. + pushIVUsers(IVOperand, L, Simplified, SimpleIVUsers); + continue; + } + CastInst *Cast = dyn_cast<CastInst>(UseInst); if (V && Cast) { V->visitCast(Cast); |