[PATCH] D149529: [SCEV][reland] More precise trip multiples

Joshua Cao via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 29 14:14:00 PDT 2023


caojoshua created this revision.
Herald added subscribers: javed.absar, hiraditya.
Herald added a project: All.
caojoshua added a comment.
caojoshua updated this revision to Diff 518234.
caojoshua added reviewers: mkazantsev, nikic.
Herald added a subscriber: StephenFan.
caojoshua published this revision for review.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

An interesting non-SCEVAddRecExpr case that failures the verification is IndVarSimplify/udiv.ll <https://github.com/llvm/llvm-project/blob/a4797869e73355209206a5175c11bedb14013211/llvm/test/Transforms/IndVarSimplify/udiv.ll>. In verification, we try to compute the multiple of `(8193 smax {6,+,3}<nuw><%for.body15>)`, which is 3. When originally caching the value for the SCEV, we had `(8193 smax {6,+,3}<%for.body15>)`, which due to the lack of nuw, has a multiple of 1.

The only write operation to a SCEV that can affect its multiple is its wrap flags, or the wrap flags of its operands. The operands themselves never change. If only the flags change, the originally cached multiple should divide the recomputed multiple.

These cases are rare, and I'd say its ok for the cached multiple to not always be the best answer, and sometimes be a conservative answer.


caojoshua added a comment.

fix typo


We currently have getMinTrailingZeros(), from which we can get a SCEV's
multiple by computing 1 << MinTrailingZeroes. However, this only gets us
multiples that are a power of 2. This patch introduces a way to get max
constant multiples that are not just a power of 2. The logic is similar
to that of getMinTrailingZeros. getMinTrailingZerosImpl is replaced by
computing the max constant multiple, and counting the number of trailing
bits.

I have so far found this useful in two places:

1. Computing unsigned constant ranges. For example, if we have i8 {10,+,10}<nuw>, we know the max constant it can be is 250.

2. My original intent was to use this in getSmallConstantTripMultiples, but it has no effect right now due to change from D110587 <https://reviews.llvm.org/D110587>. For example, if we have backedge count `(6 * %N) - 1`, the trip count becomes `1 + zext((6 * %N) - 1)`, and we cannot say that 6 is a multiple of the SCEV. I plan to look further into this separately.

The implementation assumes the value is unsigned. It can probably be
extended to handle signed values as well.

If the code sees that a SCEV does not have <nuw>, it will fall back to
finding the max multiple that is a power of 2. Multiples that are a
power of 2 will still be a multiple even after the SCEV overflows. This
does not apply to other values. This is the 1st commit message:

---

This relands https://reviews.llvm.org/D141823. The verification fails
when expensive checks are turned on. This can occur when:

1. SCEV S's multiple is cached
2. SCEV S's no wrap flags are strengthened, and the multiple changes
3. SCEV verifier finds that S's cached and recomputed multiple are different

We eliminate most cases by forgetting SCEVAddRecExpr's cached values
when the flags are modified, but there are still cases for other SCEV
types. We relax the check by making sure the cached multiple divides the
recomputed multiple, ensuring the cached multiple is correct,
conservative multiple.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149529

Files:
  llvm/include/llvm/Analysis/ScalarEvolution.h
  llvm/lib/Analysis/ScalarEvolution.cpp
  llvm/test/Analysis/ScalarEvolution/nsw.ll
  llvm/test/Analysis/ScalarEvolution/ranges.ll
  llvm/test/Analysis/ScalarEvolution/trip-multiple-guard-info.ll
  llvm/test/Analysis/ScalarEvolution/trip-multiple.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149529.518234.patch
Type: text/x-patch
Size: 20802 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230429/69293525/attachment.bin>


More information about the llvm-commits mailing list