This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Keep common NUW flags when inlining Add operands.
ClosedPublic

Authored by fhahn on Jun 8 2021, 2:34 AM.

Details

Summary

Currently, NoWrapFlags are dropped if we inline operands of SCEVAddExpr
operands. As a consequence, we always drop flags when building
expressions like getAddExpr(A, getAddExpr(B, C, NUW), NUW).

We should be able to retain NUW flags common among all inlined
SCEVAddExpr and the original flags.

Diff Detail

Event Timeline

fhahn created this revision.Jun 8 2021, 2:34 AM
fhahn requested review of this revision.Jun 8 2021, 2:34 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 8 2021, 2:34 AM

As far as I understand what is a nsw for multi-argument add, it means that there should be no wrap in between if we add the operands one by one in any order. Imagine the case when a = c = SINT_MIN and b = d = SINT_MAX. We can say that a+b has <nsw>, c+d has <nsw>, and (a+b) + (c+d) also has nsw. But if we say that getAddExpr(getAddExpr(a, b, nsw), getAddExpr(c, d, nsw), nsw) = getAddExpr(a, b, c, d, nsw), it's not true if we compute the latter as a + c + b + d. It will overflow on a + c already. Is my understanding wrong here?

fhahn updated this revision to Diff 350670.Jun 8 2021, 11:24 AM

As far as I understand what is a nsw for multi-argument add, it means that there should be no wrap in between if we add the operands one by one in any order. Imagine the case when a = c = SINT_MIN and b = d = SINT_MAX. We can say that a+b has <nsw>, c+d has <nsw>, and (a+b) + (c+d) also has nsw. But if we say that getAddExpr(getAddExpr(a, b, nsw), getAddExpr(c, d, nsw), nsw) = getAddExpr(a, b, c, d, nsw), it's not true if we compute the latter as a + c + b + d. It will overflow on a + c already. Is my understanding wrong here?

Good point, I was not aware that the flags need to apply for any order of evaluation, but it makes sense! I couldn't find any reference of that, do you think it would be worth to spell that out somewhere?

I think for NUW we should not have the same problem, right? I updated the patch to only consider common NUW flags for now.

fhahn retitled this revision from [SCEV] Keep common flags when inlining SCEVAddExpr operands. to [SCEV] Keep common NUW flags when inlining Add operands..Jun 8 2021, 11:25 AM
fhahn edited the summary of this revision. (Show Details)
nikic accepted this revision.Jun 8 2021, 1:05 PM

LGTM

llvm/lib/Analysis/ScalarEvolution.cpp
2547

nit: are have, should be only one of them.

2548

I think it would be good to explicitly mention why NSW is not preserved here.

This revision is now accepted and ready to land.Jun 8 2021, 1:05 PM
mkazantsev accepted this revision.Jun 8 2021, 9:54 PM

For nuw it should be fine. LGTM!

Good point, I was not aware that the flags need to apply for any order of evaluation

Technically, SCEV's commutative operations don't have order of operand, we only sort them to make simplification easier. So I guess it's a reasonable thing to assume. Expander, for example, may use any order to expand it.

fhahn added inline comments.Jun 9 2021, 6:26 AM
llvm/lib/Analysis/ScalarEvolution.cpp
2547

Thanks, I'll fix that!

2548

Sounds good, I'll add a comment in the committed version.

This revision was landed with ongoing or failed builds.Jun 9 2021, 9:21 AM
This revision was automatically updated to reflect the committed changes.