<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div>
<div></div>
<div><font style="color:#333333"><i>Sent from my Verizon Wireless 4G LTE DROID</i></font></div>
<div><font style="color:#333333"><i>On Feb 24, 2016 9:33 PM, Richard Smith via llvm-dev <</i></font><a href="mailto:llvm-dev@lists.llvm.org"><font style="color:#333333"><i>llvm-dev@lists.llvm.org</i></font></a><font style="color:#333333"><i>> wrote:</i></font></div>
<div><font style="color:#333333"><i>></i></font></div>
<div><font style="color:#333333"><i>> On Wed, Feb 24, 2016 at 7:17 PM, Chandler Carruth via llvm-dev</i></font></div>
<div><font style="color:#333333"><i>> <</i></font><a href="mailto:llvm-dev@lists.llvm.org"><font style="color:#333333"><i>llvm-dev@lists.llvm.org</i></font></a><font style="color:#333333"><i>> wrote:</i></font></div>
<div><font style="color:#333333"><i>> > On Wed, Feb 24, 2016 at 7:10 PM Sanjoy Das via llvm-dev</i></font></div>
<div><font style="color:#333333"><i>> > <</i></font><a href="mailto:llvm-dev@lists.llvm.org"><font style="color:#333333"><i>llvm-dev@lists.llvm.org</i></font></a><font style="color:#333333"><i>> wrote:</i></font></div>
<div><font style="color:#333333"><i>> >></i></font></div>
<div><font style="color:#333333"><i>> >> On Wed, Feb 24, 2016 at 6:51 PM, Duncan P. N. Exon Smith</i></font></div>
<div><font style="color:#333333"><i>> >> <</i></font><a href="mailto:dexonsmith@apple.com"><font style="color:#333333"><i>dexonsmith@apple.com</i></font></a><font style="color:#333333"><i>> wrote:</i></font></div>
<div><font style="color:#333333"><i>> >> >> If we do not inline @foo(), and instead re-link the call site in @main</i></font></div>
<div><font style="color:#333333"><i>> >> >> to some non-optimized copy (or differently optimized copy) of @foo,</i></font></div>
<div><font style="color:#333333"><i>> >> >> then it is possible for the program to have the behavior {print("Y");</i></font></div>
<div><font style="color:#333333"><i>> >> >> print ("X")}, which was disallowed in the earlier program.</i></font></div>
<div><font style="color:#333333"><i>> >> >></i></font></div>
<div><font style="color:#333333"><i>> >> >> In other words, opt refined the semantics of @foo() (i.e. reduced the</i></font></div>
<div><font style="color:#333333"><i>> >> >> set of behaviors it may have) in ways that would make later</i></font></div>
<div><font style="color:#333333"><i>> >> >> optimizations invalid if we de-refine the implementation of @foo().</i></font></div>
<div><font style="color:#333333"><i>> >> ></i></font></div>
<div><font style="color:#333333"><i>> >> > I'm probably missing something obvious here. How could the result of</i></font></div>
<div><font style="color:#333333"><i>> >> > `%t0 != %t1` be different at optimization time in one file than from</i></font></div>
<div><font style="color:#333333"><i>> >> > runtime in the "real" implementation? Doesn't this make the CSE</i></font></div>
<div><font style="color:#333333"><i>> >> > invalid?</i></font></div>
<div><font style="color:#333333"><i>> >></i></font></div>
<div><font style="color:#333333"><i>> >> `%t0` and `%t1` are "allowed" to "always be the same", i.e. an</i></font></div>
<div><font style="color:#333333"><i>> >> implementation of @foo that always feeds in the same</i></font></div>
<div><font style="color:#333333"><i>> >> value for `%t0` and `%t1` is a valid implementation (which is why the</i></font></div>
<div><font style="color:#333333"><i>> >> CSE was valid); but it is not the *only* valid implementation. If I</i></font></div>
<div><font style="color:#333333"><i>> >> don't CSE the two load instructions (also a valid thing to do), and</i></font></div>
<div><font style="color:#333333"><i>> >> this is a second thread writing to `%par`, then the two values loaded</i></font></div>
<div><font style="color:#333333"><i>> >> can be different, and you could end up printing `"X"` in `@foo`.</i></font></div>
<div><font style="color:#333333"><i>> >></i></font></div>
<div><font style="color:#333333"><i>> >> Did that make sense?</i></font></div>
<div><font style="color:#333333"><i>> >></i></font></div>
<div><font style="color:#333333"><i>> >> > Does linkonce_odr linkage have the same problem?</i></font></div>
<div><font style="color:#333333"><i>> >> > - If so, do you want to change it too?</i></font></div>
<div><font style="color:#333333"><i>> >> > - Else, why not?</i></font></div>
<div><font style="color:#333333"><i>> >></i></font></div>
<div><font style="color:#333333"><i>> >> Going by the specification in the LangRef, I'd say it depends on how</i></font></div>
<div><font style="color:#333333"><i>> >> you define "definitive". If you're allowed to replace the body of a</i></font></div>
<div><font style="color:#333333"><i>> >> function with a differently optimized body, then the above problem</i></font></div>
<div><font style="color:#333333"><i>> >> exists.</i></font></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> > I believe that is the case, and I strongly believe the problem you outline</i></font></div>
<div><font style="color:#333333"><i>> > exists for linkonce_odr exactly as it does for available_externally.</i></font></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> > Which is what makes this scary: every C++ inline function today can trigger</i></font></div>
<div><font style="color:#333333"><i>> > this.</i></font></div>
<div><font style="color:#333333"><i>></i></font></div>
<div><font style="color:#333333"><i>> More generally, the same problem applies to all entities within</i></font></div>
<div><font style="color:#333333"><i>> comdats (we can view available_externally and linkonce_odr as special</i></font></div>
<div><font style="color:#333333"><i>> cases of single-symbol comdats). Similar problems show up with static</i></font></div>
<div><font style="color:#333333"><i>> local variables in inline functions (where the comdats may be</i></font></div>
<div><font style="color:#333333"><i>> equivalent across object files, but aren't necessarily identical -- in</i></font></div>
<div><font style="color:#333333"><i>> particular, one can use constant initialization for a static local</i></font></div>
<div><font style="color:#333333"><i>> variable where the other uses dynamic initialization, and inlining the</i></font></div>
<div><font style="color:#333333"><i>> one with constant initialization then selecting the one with dynamic</i></font></div>
<div><font style="color:#333333"><i>> initialization results in the variable not being initialized).</i></font></div>
<div><font style="color:#333333"><i><br>
</i></font></div>
<div><font style="color:#333333"><i>Is this initialization choice currently a choice we make in the backend or the frontend?</i></font></div>
<div><font style="color:#333333"><i><br>
</i></font></div>
<div><font style="color:#333333"><i>-Hal</i></font></div>
<div><font style="color:#333333"><i><br>
</i></font></div>
<div><font style="color:#333333"><i>></i></font></div>
<div><font style="color:#333333"><i>> One approach that appears superficially correct would be to say that</i></font></div>
<div><font style="color:#333333"><i>> we cannot move information across a comdat / available_externally /</i></font></div>
<div><font style="color:#333333"><i>> linkonce_odr boundary unless doing so allows us to completely remove</i></font></div>
<div><font style="color:#333333"><i>> that reference to the comdat / function / global. (In particular, you</i></font></div>
<div><font style="color:#333333"><i>> can't use the attrs on a function in a comdat from outside that comdat</i></font></div>
<div><font style="color:#333333"><i>> -- unless you somehow know they're present for all versions of that</i></font></div>
<div><font style="color:#333333"><i>> comdat.) But that seems to have a pretty huge impact on optimizability</i></font></div>
<div><font style="color:#333333"><i>> of comdats.</i></font></div>
<div><font style="color:#333333"><i>></i></font></div>
<div><font style="color:#333333"><i>> >> >> The above example is clearly fabricated, but such cases can come up</i></font></div>
<div><font style="color:#333333"><i>> >> >> even if everything is optimized to the same level. E.g. one of the</i></font></div>
<div><font style="color:#333333"><i>> >> >> atomic loads in the unrefined implementation of @foo() could have been</i></font></div>
<div><font style="color:#333333"><i>> >> >> hidden behind a function call, whose body existed in only one module.</i></font></div>
<div><font style="color:#333333"><i>> >> >> That module would then be able to refine @foo() to `ret void` but</i></font></div>
<div><font style="color:#333333"><i>> >> >> other modules won't.</i></font></div>
<div><font style="color:#333333"><i>> >> >></i></font></div>
<div><font style="color:#333333"><i>> >> >> The only solution I can think of is to redefine available_externally</i></font></div>
<div><font style="color:#333333"><i>> >> >> to mean "the only kind of IPO/IPA you can do over a call to this</i></font></div>
<div><font style="color:#333333"><i>> >> >> function is to inline it". Redefining available_externally this way</i></font></div>
<div><font style="color:#333333"><i>> >> >> will also let us soundly use it to represent calls to functions that</i></font></div>
<div><font style="color:#333333"><i>> >> >> have guard intrinsics, since a failed guard intrinsic basically</i></font></div>
<div><font style="color:#333333"><i>> >> >> replaces the function with a "very de-refined" implementation (the</i></font></div>
<div><font style="color:#333333"><i>> >> >> interpreter).</i></font></div>
<div><font style="color:#333333"><i>> >> >></i></font></div>
<div><font style="color:#333333"><i>> >> >> What do you think? I don't think implementing the above above will be</i></font></div>
<div><font style="color:#333333"><i>> >> >> very difficult, but needless to say, it will still be a fairly</i></font></div>
<div><font style="color:#333333"><i>> >> >> non-trivial semantic change (hence I'm not directly jumping to</i></font></div>
<div><font style="color:#333333"><i>> >> >> implementation).</i></font></div>
<div><font style="color:#333333"><i>> >> ></i></font></div>
<div><font style="color:#333333"><i>> >> > This linkage is used in three places (that I know of) by clang:</i></font></div>
<div><font style="color:#333333"><i>> >> ></i></font></div>
<div><font style="color:#333333"><i>> >> > 1. C-style `inline` functions.</i></font></div>
<div><font style="color:#333333"><i>> >> > 2. Functions defined in C++ template classes with external explicit</i></font></div>
<div><font style="color:#333333"><i>> >> > instantiations, e.g. S::foo() in:</i></font></div>
<div><font style="color:#333333"><i>> >> ></i></font></div>
<div><font style="color:#333333"><i>> >> > template <class T> struct S { void foo() {} };</i></font></div>
<div><font style="color:#333333"><i>> >> > void bar() { S<int>().foo(); }</i></font></div>
<div><font style="color:#333333"><i>> >> > extern template struct S<int>;</i></font></div>
<div><font style="color:#333333"><i>> >> ></i></font></div>
<div><font style="color:#333333"><i>> >> > 3. -flto=thin cross-module function importing.</i></font></div>
<div><font style="color:#333333"><i>> >> ></i></font></div>
<div><font style="color:#333333"><i>> >> > (No comment on (1); its exact semantics are a little fuzzy to me.)</i></font></div>
<div><font style="color:#333333"><i>> >> > For (2) and (3), the current behaviour seems correct, and I'd be</i></font></div>
<div><font style="color:#333333"><i>> >> > hesitant to lose optimizing power. (2) is under the "ODR" rule, and</i></font></div>
<div><font style="color:#333333"><i>> >> > I think we've been applying the same logic to (3). Unless, are you</i></font></div>
<div><font style="color:#333333"><i>> >> > saying ODR isn't enough?</i></font></div>
<div><font style="color:#333333"><i>> >></i></font></div>
<div><font style="color:#333333"><i>> >> By ODR, do you mean you only have one definition of the function in</i></font></div>
<div><font style="color:#333333"><i>> >> the whole link (i.e. across all modules you'll link together)?</i></font></div>
<div><font style="color:#333333"><i>> >> Then yes, ODR should be enough to avoid this. But in any place where</i></font></div>
<div><font style="color:#333333"><i>> >> the linker sees two differently optimized definitions for a function</i></font></div>
<div><font style="color:#333333"><i>> >> and picks one as the definitive version all non-inlined calls link to,</i></font></div>
<div><font style="color:#333333"><i>> >> we have this problem.</i></font></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> > No, different levels of optimization must be allowed within ODR. So this is</i></font></div>
<div><font style="color:#333333"><i>> > a problem within an ODR context.</i></font></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> > (The term ODR applies to one *source* definition, not one optimized</i></font></div>
<div><font style="color:#333333"><i>> > definition)</i></font></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> > _______________________________________________</i></font></div>
<div><font style="color:#333333"><i>> > LLVM Developers mailing list</i></font></div>
<div><font style="color:#333333"><i>> > </i></font><a href="mailto:llvm-dev@lists.llvm.org"><font style="color:#333333"><i>llvm-dev@lists.llvm.org</i></font></a></div>
<div><font style="color:#333333"><i>> > </i></font><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"><font style="color:#333333"><i>http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</i></font></a></div>
<div><font style="color:#333333"><i>> ></i></font></div>
<div><font style="color:#333333"><i>> _______________________________________________</i></font></div>
<div><font style="color:#333333"><i>> LLVM Developers mailing list</i></font></div>
<div><font style="color:#333333"><i>> </i></font><a href="mailto:llvm-dev@lists.llvm.org"><font style="color:#333333"><i>llvm-dev@lists.llvm.org</i></font></a></div>
<div><font style="color:#333333"><i>> </i></font><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"><font style="color:#333333"><i>http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</i></font></a></div>
<div><font style="color:#333333"><i><br>
</i></font></div>
</div>
</body>
</html>