aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
diff options
context:
space:
mode:
authorzhongyunde <zhongyunde@huawei.com>2022-07-08 17:03:17 +0800
committerzhongyunde <zhongyunde@huawei.com>2022-07-08 17:07:20 +0800
commit716e1b856aa38ef1d988af73413e7e4aadad2ffa (patch)
tree418f0c07984eda26f4f8f92c0e82422deeed6697 /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
parent7b9a3b9d6d98184d3e20c03fceefaac6dc0c3580 (diff)
downloadllvm-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.cpp37
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);