diff options
author | zhongyunde <zhongyunde@huawei.com> | 2022-08-09 23:52:31 +0800 |
---|---|---|
committer | zhongyunde <zhongyunde@huawei.com> | 2022-08-09 23:59:42 +0800 |
commit | c2ab65ddaf4b2ab936ede3cc673de7f8f0440a48 (patch) | |
tree | 00350e82a5e87d8aa427782f7c28d7eff45f2cce /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | |
parent | 20e6239a44d61bc9a7f287c1b02baa1e5c395278 (diff) | |
download | llvm-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.cpp | 26 |
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; |