[llvm] r273079 - [SCEV] Fix incorrect trip count computation

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 19 20:47:33 PDT 2016


On Sun, Jun 19, 2016 at 3:21 PM, Sanjoy Das <sanjoy at playingwithpointers.com>
wrote:

> Hi Eli,
>
> Eli Friedman wrote:
> > It seems like it should be possible to optimize nsw-tripcount.ll
> *somehow*... you're right that the NoWrap on the
> > induction variable is irrelevant, but it should be possible to use the
> NSW property of the RHS to come up with the right
> > conclusion.
>
> You're right -- if we could model the nsw on the RHS inside SCEV then
> we could compute a constant trip count for the loop (though, in that
> case, we should not need to do anything special casing at all since
> "smax(X,X nsw+ <Constant>)" should fold to "X" or "X nsw+ <Constant>"
> depending on <Constant> anyway).
>

I'm pretty sure we don't actually do this folding.  But there are other
issues; we do actually infer nsw in the @nswnowrap testcase, but we can't
do anything useful with it because we infer it after we build the smax
expression.  (Mutating SCEV expressions seems like a terrible idea in
general.)

Unfortunately, modeling the nsw on the RHS is not a simple bugfix in
> SCEV, but will require some major infrastructure changes.  SCEV keys
> expressions on their arithmetic operands, not on their no-wrap flags.
> No-wrap flags are added to SCEV expressions by mutating them.  This
> means both "A + B" and "A nsw+ B" will map to the same SCEV*, so
> transferring the nsw from the latter llvm::Instruction to the
> corresponding llvm::SCEV* is not safe, because then we'll think
> getSCEV(A + B) is NSW when it isn't.  The test case I removed above is
> a place where this is a drawback (we can't exploit nsw as hard as we
> should be able to), but "in some cases" (I have not yet quantified
> this) it helps by making pointer equality more effective (i.e. we're
> more easily able to fold "(A + B) + (A nsw+ B)" into "2 * (A + B)").
> If we map (A+B) and (A nsw+ B) to different SCEV* then we can still
> fold "(A + B) + (A nsw+ B)" into "2 * (A + B)", but it will be more
> compile-time intensive, since we'll turn a pointer equality check into
> some kind of structural equality check.
>
> (This is work done by Bjarke Roune) In some cases, we can show that if
> an operation overflows the poison value it produced will definitely
> lead to undefined behavior, so we can transfer the nsw to SCEV*
> expressions that are guaranteed to be control equivalent to the nsw
> arithmetic.  But that logic does not apply in the deleted test case
> since neither of the two preconditions apply.
>

I see... this seems pretty messy.  Not sure I have any particular insight
beyond that.

-Eli
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160619/c8e94bd4/attachment.html>


More information about the llvm-commits mailing list