<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Jun 19, 2016 at 3:21 PM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Eli,<span><br>
<br>
Eli Friedman wrote:<br>
> It seems like it should be possible to optimize nsw-tripcount.ll *somehow*... you're right that the NoWrap on the<br>
> induction variable is irrelevant, but it should be possible to use the NSW property of the RHS to come up with the right<br>
> conclusion.<br>
<br></span>
You're right -- if we could model the nsw on the RHS inside SCEV then<br>
we could compute a constant trip count for the loop (though, in that<br>
case, we should not need to do anything special casing at all since<br>
"smax(X,X nsw+ <Constant>)" should fold to "X" or "X nsw+ <Constant>"<br>
depending on <Constant> anyway).<br></blockquote><div><br></div>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.)<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Unfortunately, modeling the nsw on the RHS is not a simple bugfix in<br>
SCEV, but will require some major infrastructure changes.  SCEV keys<br>
expressions on their arithmetic operands, not on their no-wrap flags.<br>
No-wrap flags are added to SCEV expressions by mutating them.  This<br>
means both "A + B" and "A nsw+ B" will map to the same SCEV*, so<br>
transferring the nsw from the latter llvm::Instruction to the<br>
corresponding llvm::SCEV* is not safe, because then we'll think<br>
getSCEV(A + B) is NSW when it isn't.  The test case I removed above is<br>
a place where this is a drawback (we can't exploit nsw as hard as we<br>
should be able to), but "in some cases" (I have not yet quantified<br>
this) it helps by making pointer equality more effective (i.e. we're<br>
more easily able to fold "(A + B) + (A nsw+ B)" into "2 * (A + B)").<br>
If we map (A+B) and (A nsw+ B) to different SCEV* then we can still<br>
fold "(A + B) + (A nsw+ B)" into "2 * (A + B)", but it will be more<br>
compile-time intensive, since we'll turn a pointer equality check into<br>
some kind of structural equality check.<br>
<br>
(This is work done by Bjarke Roune) In some cases, we can show that if<br>
an operation overflows the poison value it produced will definitely<br>
lead to undefined behavior, so we can transfer the nsw to SCEV*<br>
expressions that are guaranteed to be control equivalent to the nsw<br>
arithmetic.  But that logic does not apply in the deleted test case<br>
since neither of the two preconditions apply.<br></blockquote><div><br></div></div>I see... this seems pretty messy.  Not sure I have any particular insight beyond that.<span><br></span></div><div class="gmail_extra"><div class="gmail_quote"><br></div><div class="gmail_quote">-Eli<br></div></div></div>