diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index 136dfae..b749847 100644 --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -2516,38 +2516,46 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, // And select either 1. or 2. depending on whether step is positive or // negative. If Step is known to be positive or negative, only create // either 1. or 2. - Value *Add = nullptr, *Sub = nullptr; - bool NeedPosCheck = !SE.isKnownNegative(Step); - bool NeedNegCheck = !SE.isKnownPositive(Step); - - if (PointerType *ARPtrTy = dyn_cast<PointerType>(ARTy)) { - StartValue = InsertNoopCastOfTo( - StartValue, Builder.getInt8PtrTy(ARPtrTy->getAddressSpace())); - Value *NegMulV = Builder.CreateNeg(MulV); - if (NeedPosCheck) - Add = Builder.CreateGEP(Builder.getInt8Ty(), StartValue, MulV); - if (NeedNegCheck) - Sub = Builder.CreateGEP(Builder.getInt8Ty(), StartValue, NegMulV); - } else { + auto ComputeEndCheck = [&]() -> Value * { + // Checking <u 0 is always false. + if (!Signed && Start->isZero() && SE.isKnownPositive(Step)) + return ConstantInt::getFalse(Loc->getContext()); + + Value *Add = nullptr, *Sub = nullptr; + bool NeedPosCheck = !SE.isKnownNegative(Step); + bool NeedNegCheck = !SE.isKnownPositive(Step); + + if (PointerType *ARPtrTy = dyn_cast<PointerType>(ARTy)) { + StartValue = InsertNoopCastOfTo( + StartValue, Builder.getInt8PtrTy(ARPtrTy->getAddressSpace())); + Value *NegMulV = Builder.CreateNeg(MulV); + if (NeedPosCheck) + Add = Builder.CreateGEP(Builder.getInt8Ty(), StartValue, MulV); + if (NeedNegCheck) + Sub = Builder.CreateGEP(Builder.getInt8Ty(), StartValue, NegMulV); + } else { + if (NeedPosCheck) + Add = Builder.CreateAdd(StartValue, MulV); + if (NeedNegCheck) + Sub = Builder.CreateSub(StartValue, MulV); + } + + Value *EndCompareLT = nullptr; + Value *EndCompareGT = nullptr; + Value *EndCheck = nullptr; if (NeedPosCheck) - Add = Builder.CreateAdd(StartValue, MulV); + EndCheck = EndCompareLT = Builder.CreateICmp( + Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, Add, StartValue); if (NeedNegCheck) - Sub = Builder.CreateSub(StartValue, MulV); - } - - Value *EndCompareLT = nullptr; - Value *EndCompareGT = nullptr; - Value *EndCheck = nullptr; - if (NeedPosCheck) - EndCheck = EndCompareLT = Builder.CreateICmp( - Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, Add, StartValue); - if (NeedNegCheck) - EndCheck = EndCompareGT = Builder.CreateICmp( - Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT, Sub, StartValue); - if (NeedPosCheck && NeedNegCheck) { - // Select the answer based on the sign of Step. - EndCheck = Builder.CreateSelect(StepCompare, EndCompareGT, EndCompareLT); - } + EndCheck = EndCompareGT = Builder.CreateICmp( + Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT, Sub, StartValue); + if (NeedPosCheck && NeedNegCheck) { + // Select the answer based on the sign of Step. + EndCheck = Builder.CreateSelect(StepCompare, EndCompareGT, EndCompareLT); + } + return EndCheck; + }; + Value *EndCheck = ComputeEndCheck(); // If the backedge taken count type is larger than the AR type, // check that we don't drop any bits by truncating it. If we are |