<div dir="ltr"><div dir="ltr">I'm fairly certain it's simply an accident of how it's implemented in IR. At IR level, we mostly treat it as a call to a function that takes a pointer to memory. And we don't have any general function-parameter attribute which says "this call definitely overwrites the memory pointed to by this argument", nor special handling of the same sort for an inlineasm call. So, as far as the optimizer is concerned, there's a call with a pointer argument. And, as with any other call, the called "function" may read, write, or do neither to the memory pointed to by the argument.<div><br></div><div>On the other hand, for register outputs, we do handle it as an output value of the call in IR, which is why that works properly.</div><div><br></div><div>GCC does seem to optimize this properly, so I think the risk that fixing this breaks a large body of code is fairly small.</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Mar 21, 2019 at 2:23 PM JF Bastien <<a href="mailto:jfbastien@apple.com">jfbastien@apple.com</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 style="overflow-wrap: break-word;"><br><div><br><blockquote type="cite"><div>On Mar 21, 2019, at 11:14 AM, James Y Knight <<a href="mailto:jyknight@google.com" target="_blank">jyknight@google.com</a>> wrote:</div><br class="gmail-m_6479873800655919048Apple-interchange-newline"><div><div dir="ltr"><div dir="ltr"><div>If an asm's constraints claim that the variable is an output, but then don't actually write to it, that's a bug (at least if the value is actually used afterwards). An output-only constraint on inline asm definitely does _not_ mean "pass through the previous value unchanged, if the asm failed to actually write to it". If you need that behavior, it's spelled "+m", not "=m".<br></div><div><br></div><div>We do seem to fail to take advantage of this for memory outputs (again, this is not just for ftrivial-auto-var-init -- we ought to eliminate manual initialization just the same), which I'd definitely consider an missing-optimization bug.</div></div></div></div></blockquote><div><br></div><div>Agreed on both counts. Maybe we don’t do the optimization because code tends to be wrong? If that’s the case, the optimization would make people sad (even though their code is wrong). We might need to validate asm statement constraints…</div><div><br></div><div>I don’t want us to just blindly do the optimization and break code, even if said code was incorrect.</div><div><br></div><br><blockquote type="cite"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Mar 21, 2019 at 10:16 AM Alexander Potapenko <<a href="mailto:glider@google.com" target="_blank">glider@google.com</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">On Thu, Mar 21, 2019 at 2:58 PM James Y Knight <<a href="mailto:jyknight@google.com" target="_blank">jyknight@google.com</a>> wrote:<br>
><br>
> Please be more specific about the problem, because your simplified example doesn't actually show an issue. If I write this function:<br>
> int foo() {<br>
>   int retval;<br>
>   asm("# ..." : "=r"(retval));<br>
>   return retval;<br>
> }<br>
> it already does get treated as definitely writing retval, and optimizes away the initialization (whether you explicitly initialize retval, or use -ftrivial-auto-var-init).<br>
> Example: <a href="https://godbolt.org/z/YYBCXL" rel="noreferrer" target="_blank">https://godbolt.org/z/YYBCXL</a><br>
This is probably because you're passing retval as a register output.<br>
If you change "=r" to "=m" (<a href="https://godbolt.org/z/ulxSgx" rel="noreferrer" target="_blank">https://godbolt.org/z/ulxSgx</a>), it won't be<br>
optimized away.<br>
(I admit I didn't know about the difference)<br>
> On Thu, Mar 21, 2019 at 8:35 AM Alexander Potapenko via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br>
>><br>
>> Hi JF et al.,<br>
>><br>
>> In the Linux kernel we often encounter the following pattern:<br>
>><br>
>> type op(...) {<br>
>>   type retval;<br>
>>   inline asm(... retval ...);<br>
>>   return retval;<br>
>> }<br>
>><br>
>> , which is used to implement low-level platform-dependent memory operations.<br>
>><br>
>> Some of these operations turn out to be very hot, so we probably don't<br>
>> want to initialize |retval| given that it's always initialized in the<br>
>> assembly.<br>
>><br>
>> However it's practically impossible to tell that a variable is being<br>
>> written to by the inline assembly, or figure out the size of that<br>
>> write.<br>
>> Perhaps we could speculatively treat every scalar output of an inline<br>
>> assembly routine as an initialized value (which is true for the Linux<br>
>> kernel, but I'm not sure about other users of inline assembly, e.g.<br>
>> video codecs).<br>
>><br>
>> WDYT?<br>
>><br>
>><br>
>> --<br>
>> Alexander Potapenko<br>
>> Software Engineer<br>
>><br>
>> Google Germany GmbH<br>
>> Erika-Mann-Straße, 33<br>
>> 80636 München<br>
>><br>
>> Geschäftsführer: Paul Manicle, Halimah DeLaine Prado<br>
>> Registergericht und -nummer: Hamburg, HRB 86891<br>
>> Sitz der Gesellschaft: Hamburg<br>
>> _______________________________________________<br>
>> cfe-dev mailing list<br>
>> <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
>> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br>
<br>
<br>
--<br>
Alexander Potapenko<br>
Software Engineer<br>
<br>
Google Germany GmbH<br>
Erika-Mann-Straße, 33<br>
80636 München<br>
<br>
Geschäftsführer: Paul Manicle, Halimah DeLaine Prado<br>
Registergericht und -nummer: Hamburg, HRB 86891<br>
Sitz der Gesellschaft: Hamburg<br>
</blockquote></div>
</div></blockquote></div><br></div></blockquote></div>