<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Jun 19, 2016 at 9:43 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"><span class="">Hi Eli,<br>
<br>
Eli Friedman wrote:<br></span><span class="">
> Sanjoy Das wrote:<br>
> I'm pretty sure we don't actually do this folding.<br>
<br></span>
Yeah that seemed to be "obvious enough" that I didn't bother checking. :)<br>
<br>
In any case, if / once we are able to prove the tripcount of a loop<br>
is, say, smax(V, V +nsw 10) then teaching getSMax to fold smax(V,<br>
V +nsw 10) into V +nsw 10 seems like the right layering.<span class=""><br>
<br>
> But there are other issues; we do actually infer nsw in the<br>
> @nswnowrap testcase, but we can't do anything useful with it because we infer it after we build the smax expression.<br>
<br></span>
Are you talking about this case, in nsw.ll ?<br>
<br>
define void @nswnowrap(i32 %v) {<span class=""><br>
entry:<br>
  %add = add nsw i32 %v, 1<br></span>
  br label %for.body<br>
<br>
for.body:<span class=""><br>
  %i.04 = phi i32 [ %v, %entry ], [ %inc, %for.body ]<br></span><span class="">
  %inc = add nsw i32 %i.04, 1<br></span><span class="">
  tail call void @f(i32 %i.04)<br></span><span class="">
  %cmp = icmp slt i32 %i.04, %add<br></span><span class="">
  br i1 %cmp, label %for.body, label %for.end<br>
<br></span>
for.end:<br>
  ret void<br>
}<br>
<br>
<br>
?<br>
<br>
Then it does not look like SCEV ever infers `%add` is a nsw-add -- I tried<br>
`opt -analyze -scalar-evolution -scalar-evolution` and it gave me<span class=""><br>
<br>
  %add = add nsw i32 %v, 1<br></span>
  -->  (1 + %v) U: full-set S: full-set<br>
<br>
both times.<span class=""><font color="#888888"><br></font></span></blockquote><div><br></div><div>Err, different nswnowrap?  I'm talking about this:<br><br>declare void @f(i32)<br><br>; CHECK-LABEL: nswnowrap<br>; CHECK: --> {(1 + %v)<nsw>,+,1}<nsw><%for.body>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (1 + ((1 + %v)<nsw> smax %v))<br>define void @nswnowrap(i32 %v, i32* %buf) {<br>entry:<br>  %add = add nsw i32 %v, 1<br>  br label %for.body<br><br>for.body:<br>  %i.04 = phi i32 [ %v, %entry ], [ %inc, %for.body ]<br>  %inc = add nsw i32 %i.04, 1<br>  %buf.gep = getelementptr inbounds i32, i32* %buf, i32 %inc<br>  %buf.val = load i32, i32* %buf.gep<br>  %cmp = icmp slt i32 %i.04, %add<br>  tail call void @f(i32 %i.04)<br>  br i1 %cmp, label %for.body, label %for.end<br><br>for.end:<br>  ret void<br>}<br><br></div><div>The expression "((1 + %v)<nsw> smax %v)" shows up in the computed exit values, but doesn't get simplified.<br><br></div><div>-Eli<br></div></div></div></div>