diff options
author | Florian Hahn <flo@fhahn.com> | 2022-01-10 08:39:12 +0000 |
---|---|---|
committer | Florian Hahn <flo@fhahn.com> | 2022-01-10 08:49:25 +0000 |
commit | ad1b8772cf6b16c1162bb8ff425679f5ff046ae9 (patch) | |
tree | 07f05d641cf54ec7a3ff54a832d4e3ba17994996 /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | |
parent | 38916195c9ce281a44a3378da02c1abdd199db2d (diff) | |
download | llvm-ad1b8772cf6b16c1162bb8ff425679f5ff046ae9.zip llvm-ad1b8772cf6b16c1162bb8ff425679f5ff046ae9.tar.gz llvm-ad1b8772cf6b16c1162bb8ff425679f5ff046ae9.tar.bz2 |
[SCEVExpander] Only create multiplication if needed.
9345ab3a4550 updated generateOverflowCheck to skip creating checks that
always evaluate to false. This in turn means that we only need to
compute |Step| * Trip count if the result of the multiplication is
actually used.
Sink the multiplication into ComputeEndCheck, so it is only created
when there's an actual check.
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index d604623..70d284f 100644 --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -2494,21 +2494,6 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, Value *TruncTripCount = Builder.CreateZExtOrTrunc(TripCountVal, Ty); // Compute |Step| * Backedge - Value *MulV, *OfMul; - if (Step->isOne()) { - // Special-case Step of one. Potentially-costly `umul_with_overflow` isn't - // needed, there is never an overflow, so to avoid artificially inflating - // the cost of the check, directly emit the optimized IR. - MulV = TruncTripCount; - OfMul = ConstantInt::getFalse(MulV->getContext()); - } else { - auto *MulF = Intrinsic::getDeclaration(Loc->getModule(), - Intrinsic::umul_with_overflow, Ty); - CallInst *Mul = Builder.CreateCall(MulF, {AbsStep, TruncTripCount}, "mul"); - MulV = Builder.CreateExtractValue(Mul, 0, "mul.result"); - OfMul = Builder.CreateExtractValue(Mul, 1, "mul.overflow"); - } - // Compute: // 1. Start + |Step| * Backedge < Start // 2. Start - |Step| * Backedge > Start @@ -2521,6 +2506,22 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, if (!Signed && Start->isZero() && SE.isKnownPositive(Step)) return ConstantInt::getFalse(Loc->getContext()); + Value *MulV, *OfMul; + if (Step->isOne()) { + // Special-case Step of one. Potentially-costly `umul_with_overflow` isn't + // needed, there is never an overflow, so to avoid artificially inflating + // the cost of the check, directly emit the optimized IR. + MulV = TruncTripCount; + OfMul = ConstantInt::getFalse(MulV->getContext()); + } else { + auto *MulF = Intrinsic::getDeclaration(Loc->getModule(), + Intrinsic::umul_with_overflow, Ty); + CallInst *Mul = + Builder.CreateCall(MulF, {AbsStep, TruncTripCount}, "mul"); + MulV = Builder.CreateExtractValue(Mul, 0, "mul.result"); + OfMul = Builder.CreateExtractValue(Mul, 1, "mul.overflow"); + } + Value *Add = nullptr, *Sub = nullptr; bool NeedPosCheck = !SE.isKnownNegative(Step); bool NeedNegCheck = !SE.isKnownPositive(Step); |