<div dir="ltr">The thread is long and I haven't read it all, but I like the approach of:<div>- add a new noipa LLVM IR attribute (feel free to bikeshed the name)</div><div>- make clang optnone imply noipa (maybe in LLVM too, but I haven't thought hard about it)</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Apr 18, 2021 at 9:37 AM David Blaikie via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">While trying to reproduce some debug info thing (I don't have the exact example at the moment - but I think it was more aggressive than the example I have now, but something like this:<br><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace">__attribute__((optnone)) int f1() {<br></font><font face="monospace">  return 3;<br></font><font face="monospace">}<br></font><font face="monospace">int main() {<br></font><font face="monospace">  return f1();<br></font><font face="monospace">}</font></blockquote><br>(actually I think in my case I had a variable to hold the return value from f1, with the intent that this variable's location couldn't use a constant - a load from a volatile variable would probably have provided similar functionality in this case)<br><br>LLVM (& specifically Sparse Conditional Constant Propagation, llvm/lib/Transforms/Scalar/SCCP.cpp) optimizes this code noting that f1 always returns 3, so rather than using the return value from the call to f1, it ends up hardcoding the return value:<br><br>





<blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures">define dso_local i32 @main() local_unnamed_addr #1 {</span></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures">entry:</span></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures"><span>  </span>%call = tail call i32 @_Z2f1v()</span></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures"><span>  </span>ret i32 3</span></p><p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures">}</span></p></blockquote>



<br>I consider this a bug - in that optnone is used to implement -O0 for LTO, so it seemed to me that the correct behavior is for an optnone function to behave as though it were compiled in another object file outside the purview of optimizations - interprocedural or intraprocedural.<br><br>So I sent <a href="https://reviews.llvm.org/D100353" target="_blank">https://reviews.llvm.org/D100353</a> to fix that.<br><br>Florian pointed out that this wasn't quite specified in the LangRef, which says this about optnone:<br><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><p style="margin:0px 0px 0.5em;color:rgb(0,0,0);font-family:"Lucida Grande","Lucida Sans Unicode",Geneva,Verdana,sans-serif;font-size:14px">This function attribute indicates that most optimization passes will skip this function, with the exception of interprocedural optimization passes. Code generation defaults to the “fast” instruction selector. This attribute cannot be used together with the <code style="font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono",monospace;font-size:0.95em"><span>alwaysinline</span></code> attribute; this attribute is also incompatible with the <code style="font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono",monospace;font-size:0.95em"><span>minsize</span></code> attribute and the <code style="font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono",monospace;font-size:0.95em"><span>optsize</span></code> attribute.</p><p style="margin:0px 0px 0.5em;color:rgb(0,0,0);font-family:"Lucida Grande","Lucida Sans Unicode",Geneva,Verdana,sans-serif;font-size:14px">This attribute requires the <code style="font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono",monospace;font-size:0.95em"><span>noinline</span></code> attribute to be specified on the function as well, so the function is never inlined into any caller. Only functions with the <code style="font-family:Consolas,"Deja Vu Sans Mono","Bitstream Vera Sans Mono",monospace;font-size:0.95em"><span>alwaysinline</span></code> attribute are valid candidates for inlining into the body of this function.</p></blockquote><br>So the spec of optnone is unclear (or arguably explicitly disallows) whether interprocedural optimizations should treat optnone functions in any particular way.<br><br>So I was going to update the wording to rephrase this to say "Interprocedural optimizations should treat this function as though it were defined in an isolated module/object." (perhaps "interprocedural optimizations should treat optnone functions as opaque" or "as though they were only declarations")<br><br>The choice of this direction was based on my (possibly incorrect or debatable) understanding of optnone, that it was equivalent to the function being in a separate/non-lto object. (this seems consistent with the way optnone is used to implement -O0 under lto - you could imagine a user debugging a binary, using -O0 for the code they're interested in debugging, and potentially using an interactive debugger to change some state in the function causing it to return a different value - which would get quite confusing if the return value was effectively hardcoded into the caller)<br><br>What're folks thoughts on this?<br><br>- Dave</div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>