aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
diff options
context:
space:
mode:
authorzhongyunde <zhongyunde@huawei.com>2022-08-09 23:52:31 +0800
committerzhongyunde <zhongyunde@huawei.com>2022-08-09 23:59:42 +0800
commitc2ab65ddaf4b2ab936ede3cc673de7f8f0440a48 (patch)
tree00350e82a5e87d8aa427782f7c28d7eff45f2cce /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
parent20e6239a44d61bc9a7f287c1b02baa1e5c395278 (diff)
downloadllvm-c2ab65ddaf4b2ab936ede3cc673de7f8f0440a48.zip
llvm-c2ab65ddaf4b2ab936ede3cc673de7f8f0440a48.tar.gz
llvm-c2ab65ddaf4b2ab936ede3cc673de7f8f0440a48.tar.bz2
[IndVars] Eliminate redundant type cast with different sizes
Deal with different sizes between the itofp and fptoi with trunc or sext/zext, depend on D129756. Fixes https://github.com/llvm/llvm-project/issues/55505. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D129958
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyIndVar.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 0ab79a3..0a856ee 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -683,7 +683,7 @@ bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) {
UseInst->getOpcode() != CastInst::UIToFP)
return false;
- Value *IVOperand = UseInst->getOperand(0);
+ Instruction *IVOperand = cast<Instruction>(UseInst->getOperand(0));
// Get the symbolic expression for this instruction.
const SCEV *IV = SE->getSCEV(IVOperand);
unsigned MaskBits;
@@ -696,17 +696,35 @@ bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) {
for (User *U : UseInst->users()) {
// Match for fptosi/fptoui of sitofp and with same type.
auto *CI = dyn_cast<CastInst>(U);
- if (!CI || IVOperand->getType() != CI->getType())
+ if (!CI)
continue;
CastInst::CastOps Opcode = CI->getOpcode();
if (Opcode != CastInst::FPToSI && Opcode != CastInst::FPToUI)
continue;
- CI->replaceAllUsesWith(IVOperand);
+ Value *Conv = nullptr;
+ if (IVOperand->getType() != CI->getType()) {
+ IRBuilder<> Builder(CI);
+ StringRef Name = IVOperand->getName();
+ // To match InstCombine logic, we only need sext if both fptosi and
+ // sitofp are used. If one of them is unsigned, then we can use zext.
+ if (SE->getTypeSizeInBits(IVOperand->getType()) >
+ SE->getTypeSizeInBits(CI->getType())) {
+ Conv = Builder.CreateTrunc(IVOperand, CI->getType(), Name + ".trunc");
+ } else if (Opcode == CastInst::FPToUI ||
+ UseInst->getOpcode() == CastInst::UIToFP) {
+ Conv = Builder.CreateZExt(IVOperand, CI->getType(), Name + ".zext");
+ } else {
+ Conv = Builder.CreateSExt(IVOperand, CI->getType(), Name + ".sext");
+ }
+ } else
+ Conv = IVOperand;
+
+ CI->replaceAllUsesWith(Conv);
DeadInsts.push_back(CI);
LLVM_DEBUG(dbgs() << "INDVARS: Replace IV user: " << *CI
- << " with: " << *IVOperand << '\n');
+ << " with: " << *Conv << '\n');
++NumFoldedUser;
Changed = true;