<div dir="auto"><div><p style="">It seems that this optimization should not be performed when strict aliasing is disabled. However, GCC is being aggressive and performs speculative loads on struct fields even with-fno-strict-aliasing.</p><p style="">Should LLVM perform this load speculation even with strict aliasing disabled?</p><p style="">If no, what is the way to check for strict aliasing in the midend (with strict aliasing being a frontend concept)? Is it reasonable to check for presence of TBAA tags on the load instructions? And if there are any TBAA tags associated with loads, consider strict aliasing enabled.</p><div class="gmail_quote"><div dir="ltr">Best, </div><div dir="ltr">Alex</div><div dir="ltr"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
-----Original Message-----<br>
From: cfe-dev [mailto:<a href="mailto:cfe-dev-bounces@lists.llvm.org" target="_blank" rel="noreferrer">cfe-dev-bounces@lists.llvm.org</a>] On Behalf Of Kreitzer, David L via cfe-dev<br>
Sent: Monday, October 09, 2017 5:17 PM<br>
To: <a href="mailto:cfe-dev@lists.llvm.org" target="_blank" rel="noreferrer">cfe-dev@lists.llvm.org</a><br>
Subject: [cfe-dev] Speculative load optimization<br>
<br>
This llvm patch, <a href="https://reviews.llvm.org/D37289" rel="noreferrer noreferrer" target="_blank">https://reviews.llvm.org/D37289</a>, attempts to do an optimization that involves speculating loads. The patch itself needs some work regardless, but we are questioning the legality of the optimization, which is currently performed by both gcc and icc. The desired transformation looks like this:<br>
<br>
    typedef struct S {<br>
      char padding[4088];<br>
      struct S *p1;<br>
      struct S *p2;<br>
    } S;<br>
<br>
    struct S* f1(struct S *s, int x)<br>
    {<br>
      S *r;<br>
      if (x)<br>
        r = s->p1;<br>
      else<br>
        r = s->p2;<br>
      return r;<br>
    }<br>
<br>
TO<br>
<br>
    struct S* f1(struct S *s, int x)<br>
    {<br>
      return (x) ? s->p1 : s->p2;<br>
    }<br>
<br>
The fundamental question seems to be whether loading one member of struct S makes it valid to load other members of the same struct. Both gcc & icc seem to think so and make a distinction between this case and a similar case where one field is accessed through an lvalue of a different type:<br>
<br>
    typedef struct T {<br>
      char padding[4088];<br>
      struct S *p1;<br>
    } T;<br>
<br>
    struct S* f2(struct S *s, int x)<br>
    {<br>
      S *r;<br>
      if (x)<br>
        r = ((T*)s)->p1;<br>
      else<br>
        r = s->p2;<br>
      return r;<br>
    }<br>
<br>
Neither compiler will transform this case.<br>
<br>
Any insight on the validity of this optimization in relation to the C/C++ standards would be appreciated.<br>
<br>
Thanks,<br>
Dave Kreitzer<br>
Intel Compilers<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" rel="noreferrer">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div></div>