<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 14, 2017 at 5:51 AM, Hubert Tong <span dir="ltr"><<a href="mailto:hubert.reinterpretcast@gmail.com" target="_blank">hubert.reinterpretcast@gmail.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"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="gmail-h5">On Mon, Feb 13, 2017 at 10:39 PM, Daniel Berlin <span dir="ltr"><<a href="mailto:dberlin@dberlin.org" target="_blank">dberlin@dberlin.org</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"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="gmail-m_-6297801910469902941h5">On Mon, Feb 13, 2017 at 10:07 AM, Hubert Tong <span dir="ltr"><<a href="mailto:hubert.reinterpretcast@gmail.com" target="_blank">hubert.reinterpretcast@gmail.<wbr>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"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="gmail-m_-6297801910469902941m_3430444186328652481h5">On Mon, Feb 13, 2017 at 2:23 AM, Daniel Berlin via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</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"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="gmail-m_-6297801910469902941m_3430444186328652481m_2542392842986513627h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-m_-6297801910469902941m_3430444186328652481m_2542392842986513627m_-1423050781334394079gmail-"><br>
</span>I don't think this fully solves the problem -- you'll also need to fix<br>
getMostGenericTBAA.  That is, even if you implement the above scheme,<br>
say you started out with:<br>
<span class="gmail-m_-6297801910469902941m_3430444186328652481m_2542392842986513627m_-1423050781334394079gmail-"><br>
union U {<br>
  int i;<br>
  float f;<br>
</span>};<br>
<br>
float f(union U *u, int *ii, float *ff, bool c) {<br>
  if (c) {<br>
    *ii = 10;<br>
    *ff = 10.0;<br>
  } else {<br>
    u->i = 10;    // S0<br>
    u->f = 10.0;  // S1<br>
  }<br>
  return u->f;<br>
}<br>
<br>
(I presume you're trying to avoid reordering S0 and S1?)<br>
<br>
SimplifyCFG or some other such pass may transform f to:<br>
<br>
float f(union U *u, int *ii, float *ff, bool c) {<br>
  int *iptr = c ? ii : &(u->i);<br>
  int *fptr = c ? ff : &(u->f);<br>
  *iptr = 10;     // S2<br>
  *fptr = 10.0;   // S3<br>
  return u->f;<br>
}<br>
<br>
then getMostGenericTBAA will infer scalar "int" TBAA for S2 and scalar<br>
"float" TBAA for S3, which will be NoAlias and allow the reordering<br>
you were trying to avoid.<br></blockquote><div><br></div></div></div><div>FWIW, i have to read this in detail, but a few things pop out at me.</div><div><br>1. We would like to live in a world where we don't depend on TBAA overriding BasicAA to get correct answers.  We do now, but don't want to.<br>Hopefully this proposal does not make that impossible.</div><div><br></div><div>2.  Literally the only way that GCC ends up getting this right is two fold:</div><div>It only guarantees things about direct access through union.</div><div>If you take the address of the union member (like the transform above), it knows it will get a wrong answer.</div><div>So what it does is it finds the type it has to stop at (here, the union) to keep the TBAA set the same, and makes the transform end there.</div><div>So the above would not occur.</div><div><br></div><div><br></div><div>3. A suggestion that TBAA follow all possible paths seems .. very slow.</div><div><br></div><div>4. "<span style="font-family:sans-serif">The main motivation for this is functional correctness of code using unions".  I believe you mean "with tbaa and strict-aliasing on".</span></div><div><span style="font-family:sans-serif">If not,functional correctness for unions should not be in any way related to requiring TBAA.</span></div><div><br></div><div>5. Unions are among the worst area of the standard in terms of "nobody has really thought super-hard about the interaction of aliasing and unions in a way that is coherent".<br></div><div>So when you say things like 'necessary for functional correctness of unions', just note that this is pretty much wrong.  You probably mean "necessary for a reasonable interpretation" or something.</div><div><br></div><div>Because we would be *functionally correct* by the standard by destroying the program  if you ever read the member you didn't set :)</div></div></div></div></blockquote><div></div></div></div><div>C11 subclause 6.5.2.3 paragraph 3, has in footnote 95:<br></div><div>If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.<br><br></div><div>So, the intent is at least that the use of the . operator or the -> operator to access a member of a union would "safely" perform type punning.</div><span><div> </div></span></div></div></div></blockquote></div></div><div>Certainly, if you can quote this, you know this is new to C11 (and newer versions of C++).</div><div>:)</div></div></div></div></blockquote></div></div><div>Yes, this is new to C11; however, the question for us here is whether, and under what options, we would support such intended use of the language.<br></div></div></div></div></blockquote><div><br></div><div>I was on board with it :)</div><div> I remember pointing out most of the cases we have bugs for when struct-path TBAA was designed (on a whiteboard, in fact) and the consensus answer i got back was basically "we'll just punt on unions for now".  I did say i suspected this would not work out well, soundness wise, but the clear consensus was against me, so here we are :)</div><div>In any case, reading this in detail:<br></div><div class="gmail_quote">1. "In<span style="font-family:sans-serif"> the struct path TBAA, it is assumed that the length of a member extends</span></div><font size="2" face="sans-serif">to the start of the next.  This will not be true for unions."</font></div><div class="gmail_quote"><font size="2" face="sans-serif"><br></font></div><div class="gmail_quote"><font size="2" face="sans-serif">Staring at the langref, i don't see where it assumes this.</font></div><div class="gmail_quote"><font size="2" face="sans-serif">it is just offset, size, tbaa type, which seems correct to me.</font></div><div class="gmail_quote"><font size="2" face="sans-serif"><br></font></div><div class="gmail_quote"><font size="2" face="sans-serif">If you mean "the implementation assumes", then yeah, the implementation should just be fixed.</font></div><div class="gmail_quote"><font size="2" face="sans-serif"><br></font></div><div class="gmail_quote"><font size="2" face="sans-serif">"</font><span style="font-family:sans-serif">In TypeBasedAAResult::alias, we will also have to deal with the fact that unions</span></div><font size="2" face="sans-serif">have multiple members all at offset 0.  This means that, unlike structs, the</font><br style="font-size:12.8px"><font size="2" face="sans-serif">compiler will not be able to tell which member of the union the memory reference</font><br style="font-size:12.8px"><font size="2" face="sans-serif">actually used.  To deal with this, TypeBasedAAResult::alias (and the functions</font><br style="font-size:12.8px"><font size="2" face="sans-serif">it calls) will have to acts as if all of the unions members could have been</font><br style="font-size:12.8px"><font size="2" face="sans-serif">accessed. "</font></div><div class="gmail_extra"><font face="sans-serif"><br></font></div><div class="gmail_extra"><font face="sans-serif">Actually, for correctness, it just has to give a conservative answer of "may-alias"</font></div><div class="gmail_extra"><br></div><div class="gmail_extra">This is papering over the fact that if it does that, basicaa overrides it.</div><div class="gmail_extra">That we should just fix that, not rely on making TBAA work harder to be correct (working harder to optimize is fine).</div><div class="gmail_extra"><br></div><div class="gmail_extra">That is, say "these are may-alias, this is a final answer" instead of "these are may-alias, maybe you can do better?"</div><div class="gmail_extra"><br></div><div class="gmail_extra"><font face="sans-serif">But yes, if you are trying to optimize unions harder (and i don't know why you would :P), yes, you'd have to follow all intersecting members.</font></div><div class="gmail_extra"><span style="font-family:sans-serif">In gcc we just sort the list, and use offset, size info to see what  fields it overlaps with.</span></div><div class="gmail_extra"><br></div><div class="gmail_extra">But note: Your correctness still depends on being able to tell these are union accesses.</div><div class="gmail_extra">That's bad, because as sanjoy says, we do transforms that may cause this to be non-recoverable.</div><div class="gmail_extra"><br></div><div class="gmail_extra">If you can't have TBAA say "may-alias, final answer", you lose.</div><div class="gmail_extra"><br></div><div class="gmail_extra">(Note, while you are improving this, i'll note the info should also be used to differentiate structure fields and solve the issue discussed here:</div><div class="gmail_extra"><a href="http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160523/date.html">http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160523/date.html</a><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">The offset, size info is useful and should be used to differentiate struct accesses *regardless of type* in cases where we can.</div><div class="gmail_extra">It doesn't actually matter if one field is an int and the other a float. If they are different fields, and we can prove it, they can't alias anyway)</div><div class="gmail_extra"><br></div><div class="gmail_extra"><font size="2" face="sans-serif"></font><div class="gmail_quote"><font size="2" face="sans-serif"><br></font></div><div class="gmail_quote"><font face="sans-serif"><br></font><font size="2" face="sans-serif"></font><div><br></div></div></div></div>