diff options
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; |