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
780

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())?

800

Isn't [this] enough?

Can it be const Value and const Instruction?

811

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?

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

?

897

Should we have a separate statistics for that?

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

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

843

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
251–252
401–402

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.

808–822

Please, spell the list of supported predicated explicitly here.

841

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
401–402

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
808–822

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
841

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
820

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