Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -260,6 +260,10 @@ // (set to UINT_MAX to disable). This does not apply in cases where the // loop is being fully unrolled. unsigned MaxCount; + /// Set the maximum unrolling factor for full unrolling. Like MaxCount, but + /// applies even if full unrolling is selected. This allows a target to fall + /// back to Partial unrolling if full unrolling is above FullUnrollMaxCount. + unsigned FullUnrollMaxCount; /// Allow partial unrolling (unrolling of loops to expand the size of the /// loop body, not only to eliminate small constant-trip-count loops). bool Partial; Index: lib/Transforms/Scalar/LoopUnrollPass.cpp =================================================================== --- lib/Transforms/Scalar/LoopUnrollPass.cpp +++ lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -107,6 +107,7 @@ UP.PartialOptSizeThreshold = UP.OptSizeThreshold; UP.Count = 0; UP.MaxCount = UINT_MAX; + UP.FullUnrollMaxCount = UINT_MAX; UP.Partial = false; UP.Runtime = false; UP.AllowExpensiveTripCount = false; @@ -566,6 +567,7 @@ Count = TripCount == 0 ? DefaultUnrollRuntimeCount : TripCount; if (TripCount && Count > TripCount) Count = TripCount; + Count = std::min(Count, UP.FullUnrollMaxCount); unsigned NumInlineCandidates; bool NotDuplicatable; @@ -633,10 +635,12 @@ << "-unroll-allow-partial not given\n"); return false; } - if (UP.PartialThreshold != NoThreshold && - UnrolledSize > UP.PartialThreshold) { + if (UP.PartialThreshold != NoThreshold) { // Reduce unroll count to be modulo of TripCount for partial unrolling. - Count = (std::max(UP.PartialThreshold, 3u) - 2) / (LoopSize - 2); + if (UnrolledSize > UP.PartialThreshold) + Count = (std::max(UP.PartialThreshold, 3u) - 2) / (LoopSize - 2); + if (Count > UP.MaxCount) + Count = UP.MaxCount; while (Count != 0 && TripCount % Count != 0) Count--; }