This is an archive of the discontinued LLVM Phabricator instance.

[LoopPredication] Widen checks if condition operands constant ranges are known
Needs RevisionPublic

Authored by dmakogon on Nov 8 2022, 4:02 AM.

Details

Summary

This enables LoopPredication to widen checks of the following form:

x < guardLimit,

where x and guardLimit have known constant ranges (meaning they are not
full-set). If they are reasonably small and max(x) <= max(guardLimit), we
can predicate the loop with the condition max(x) <= guardLimit.

Diff Detail

Event Timeline

dmakogon created this revision.Nov 8 2022, 4:02 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 8 2022, 4:02 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
dmakogon requested review of this revision.Nov 8 2022, 4:02 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 8 2022, 4:02 AM
mkazantsev added inline comments.Nov 9 2022, 2:33 AM
llvm/lib/Transforms/Scalar/LoopPredication.cpp
789

Need to make it clear that Guard always belongs to loop, but here we are filtering away guards from nested loops. Assert on L.contains(Guard->getParent())?

809

Isn't [this] enough?

Can it be const Value and const Instruction?

820

Not very informative, can we instead print one message, in the end, and make it verbose? Like, "Speculating LHS = ... less than RHS = ... because max(LHS) < max(RHS)" or something?

852
if (IsSigned)
  LHSMaxIsGreaterThanRHSMax = LHSMaxValue.sgt(RHSMaxValue);
else
  HSMaxIsGreaterThanRHSMax = LHSMaxValue.ugt(RHSMaxValue);

?

909

Should we have a separate statistics for that?

yrouban added inline comments.
llvm/lib/Transforms/Scalar/LoopPredication.cpp
840

do it right after RHSRange = ComputeRange() and only then calculate LHSRange.

852

or

bool LHSMaxIsGreaterThanRHSMax = IsSigned
                               ? LHSMaxValue.sgt(RHSMaxValue)
                               : LHSMaxValue.ugt(RHSMaxValue);

or even a bigger change without introduced LHSMaxValue and RHSMaxValue:

bool IsGreaterThanRHSMax = IsSigned
                         ? LHSRange.getSignedMax().sgt(RHSRange.getSignedMax())
                         : LHSRange.getUnsignedMax().ugt(RHSRange.getUnsignedMax());
apilipenko added inline comments.Nov 14 2022, 4:28 PM
llvm/lib/Transforms/Scalar/LoopPredication.cpp
248–249
404–405

This is a non-canonical way to get an analysis. This way it will not benefit from analysis manager caching. I guess you have to do this because LVI is a function analysis but a part of LoopStandardAnalysisResults.

I'm not sure how we should go about it, but I suggest splitting the LVI off from the initial patch. You can still get the constant range from ValueTracking to get the basic version of this optimization.

817–831

Please, spell the list of supported predicated explicitly here.

850

Why do you need to check this?

dmakogon updated this revision to Diff 478475.Nov 29 2022, 12:12 AM

Addressed comments

dmakogon marked 10 inline comments as done.Nov 29 2022, 12:21 AM
dmakogon added inline comments.
llvm/lib/Transforms/Scalar/LoopPredication.cpp
404–405

Removed LVI from this patch. Please note the test changes. I explicitly inserted assumes of dominating branches conditions to allow for the widening to happen

apilipenko added inline comments.Dec 7 2022, 11:30 AM
llvm/lib/Transforms/Scalar/LoopPredication.cpp
817–831

Could you please, spell the list of *supported* predicates explicitly?

dmakogon updated this revision to Diff 492102.Jan 25 2023, 7:24 AM
dmakogon marked an inline comment as done.

Rebase, address comments

dmakogon marked an inline comment as done.Jan 25 2023, 7:29 AM
dmakogon added inline comments.
llvm/lib/Transforms/Scalar/LoopPredication.cpp
850

Well, this is the speculation condition we decided to use. The idea here is the following:
Assume LHS is an index and RHS is array length.
So we'd like to speculate only if the index possible maximum value isn't greater that the array length maximum value.
Otherwise we assume that index would take the value greater than the array length in most cases, so we'd deoptimize.
We don't have exact statistics that such cases prevail, it's just our expectations I guess. Also here we cut off the case when LHS has a full-set range.

mkazantsev added inline comments.Feb 5 2023, 11:23 PM
llvm/lib/Transforms/Scalar/LoopPredication.cpp
829

In the switch above:

  case CmpInst::ICMP_SGE:
  case CmpInst::ICMP_UGT:
  case CmpInst::ICMP_UGE:
  case CmpInst::ICMP_SGT:
    std::swap(LHS, RHS);
    Pred = ICmpInst::getSwappedPredicate(Pred);
    LLVM_FALLTHROUGH
// Allowed predicates:
    break;
default:
  return nullptr
mkazantsev requested changes to this revision.Apr 12 2023, 10:18 PM

Marking to remove it from my review list, please update if you have plans on it.

This revision now requires changes to proceed.Apr 12 2023, 10:18 PM