This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Infer nuw from nw for addrecs
ClosedPublic

Authored by reames on Aug 23 2021, 5:50 PM.

Details

Summary

Noticed this while working on another patch. Was originally going to just land it, but it seemed a little too obvious and I'm tired. Is there something I'm missing here?

Diff Detail

Event Timeline

reames created this revision.Aug 23 2021, 5:50 PM
reames requested review of this revision.Aug 23 2021, 5:50 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2021, 5:50 PM

This does appear correct to me.

This revision was not accepted when it landed; it landed in state Needs Review.Aug 24 2021, 8:53 AM
This revision was automatically updated to reflect the committed changes.
nikic added inline comments.Aug 24 2021, 9:06 AM
llvm/lib/Analysis/ScalarEvolution.cpp
2398

Why the IsKnownNonNegative check for the NUW case? Shouldn't this be on NSW?

lebedev.ri added inline comments.Aug 24 2021, 9:16 AM
llvm/lib/Analysis/ScalarEvolution.cpp
2393–2394

Comment implies that the step must be non-negative in both cases,
but enforces that only in the first case.

For the record, this

This does appear correct to me.

isn't approval. There's 'accept revision' for that.
I'm not sure just how much more softly do i need to word that message to convey that.

reames added inline comments.Aug 24 2021, 9:37 AM
llvm/lib/Analysis/ScalarEvolution.cpp
2398

We definitely need it for NSW - I'd apparently dropped it for the NSW case when rebasing this. Oops.

For the unsigned case, I'll be honest and say I'm not sure. I get really confused about the interpretation of the signed integer overflow rules on add. The case I was thinking of was starting at 0, and adding -1. Does that violate nuw or not? If it does, we need the positive check. If it doesn't, we probably don't. Now that I write this, I'm pretty sure the answer is we don't, but I regularly get confused by that case, so I'll let someone else confirm. :)

Keeping in mind that SCEV and IR mix flag interpretations oddly, I'm strongly tempted to keep the non-negative test for (my) sanity sake even if we don't strictly speaking need it.

For the record, this

This does appear correct to me.

isn't approval. There's 'accept revision' for that.
I'm not sure just how much more softly do i need to word that message to convey that.

Sorry I misread your intent. It certainly read like approval to me, but well, my screw up. Reverted, and review resumed. Will wait for an explicit LGTM.

reames updated this revision to Diff 368376.Aug 24 2021, 9:44 AM

Add missing non-negative check to NSW case.

reames reopened this revision.Aug 24 2021, 9:44 AM
nikic added inline comments.Aug 24 2021, 10:17 AM
llvm/lib/Analysis/ScalarEvolution.cpp
2398

If you think about it as not adding 0 and -1, but rather 0 and 0xffffffff, then it becomes more obvious that it's nuw. I'd prefer not having an unnecessary isKnownNonNegative check here -- doing sign checks for unsigned arithmetic is usually an indication that some logic isn't right...

(And if we don't need to check the sign, we can drop the Ops.size() == 2 limitation for the nuw case as well.)

reames updated this revision to Diff 368404.Aug 24 2021, 11:05 AM
reames retitled this revision from [SCEV] Infer nsw/nuw from nw for addrecs to [SCEV] Infer nuw from nw for addrecs.

Implement review comment and narrow scope to nuw only.

I'll come back to the nsw case separately, but a) nuw is what's actually blocking me, and b) with the focus on generality in the review comments, we should do the same for nsw which requires a bit more code motion than I want to roll into this patch.

lebedev.ri requested changes to this revision.Aug 24 2021, 11:15 AM

Now this i don't think is right.

llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll
514 ↗(On Diff #368404)

Alive doesn't like this
https://alive2.llvm.org/ce/z/T5MNLf

This revision now requires changes to proceed.Aug 24 2021, 11:15 AM
nikic added inline comments.Aug 24 2021, 1:04 PM
llvm/lib/Analysis/ScalarEvolution.cpp
2398

Okay, looks like I was wrong here! The bit I was missing is that nw is actually a signed property:

/// AddRec expressions may have a no-self-wraparound <NW> property if, in
/// the integer domain, abs(step) * max-iteration(loop) <=
/// unsigned-max(bitwidth).  This means that the recurrence will never reach
/// its start value if the step is non-zero.  Computing the same value on
/// each iteration is not considered wrapping, and recurrences with step = 0
/// are trivially <NW>.  <NW> is independent of the sign of step and the
/// value the add recurrence starts with.

Note the abs(step) in the definition. So we do need to ensure that the step is non-negative, to make sure that abs(step) is just step.

reames added inline comments.Aug 24 2021, 2:04 PM
llvm/lib/Analysis/ScalarEvolution.cpp
2398

Yeah, I'd just worked my way to the same conclusion. For my own future reference, here's the chain of logic.

no-self-wrap is a property which describes the space traversed. It is not a wrapping property per se.

(0,+, 255) in 8 bit math represents a value which decreases by one on each iteration (by wrapping through unsigned). Putting NUW on this generates poison on the 2nd iteration. NW on the other hand, is not violated because the number of values traversed (assuming BTC is small) is less than 255.

We need the non-negative restriction to line up the restriction in terms of values traversed with the NUW definition.

reames updated this revision to Diff 368460.Aug 24 2021, 2:05 PM

Add back the positive restriction. The affine restriction could possibly be relaxed in the future.

lebedev.ri accepted this revision.Aug 24 2021, 2:13 PM

LG

llvm/lib/Analysis/ScalarEvolution.cpp
2393
This revision is now accepted and ready to land.Aug 24 2021, 2:13 PM
This revision was landed with ongoing or failed builds.Aug 24 2021, 2:24 PM
This revision was automatically updated to reflect the committed changes.