<div dir="ltr">I think ternary is equivalent to an if in that only one side is evaluated. But I think you're saying that gcc and icc will dereference s for both sides of the if and then select between the loaded values.  Like this<div><br></div><div><span style="font-size:12.8px">    struct S* f1(struct S *s, int x)</span><br style="font-size:12.8px"><span style="font-size:12.8px">    {</span></div><div>      struct S *a = s->p1;</div><div>      struct S *b = s->p2;<br style=""><span style="font-size:12.8px">      return (x) ? a : b;</span><br style="font-size:12.8px"><span style="font-size:12.8px">    }</span><br></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div>
<br><div class="gmail_quote">On Mon, Oct 9, 2017 at 2:16 PM, Kreitzer, David L via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This llvm patch, <a href="https://reviews.llvm.org/D37289" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D37289</a>, attempts to do an optimization<br>
that involves speculating loads. The patch itself needs some work regardless,<br>
but we are questioning the legality of the optimization, which is currently<br>
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<br>
makes it valid to load other members of the same struct. Both gcc & icc<br>
seem to think so and make a distinction between this case and a similar case<br>
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++<br>
standards would be appreciated.<br>
<br>
Thanks,<br>
Dave Kreitzer<br>
Intel Compilers<br>
<br>
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</blockquote></div><br></div>