<div dir="ltr"><div><div><div>I suspect <br><br><span class="gmail-im">> r = ((T*)s)->p1;<br><br></span></div><span class="gmail-im">Is allowed under </span><span class="gmail-im">C99 </span><span class="gmail-im">§6.5, strict aliasing rule<br></span></div><div>An object shall have its stored value accessed only by an lvalue
expression that has one of the following types</div><div>...<br></div><div>- an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a
subaggregate or contained union)<br><br></div>CMIIW, the cmov optimizer may be pessimistic here -- access to one path implies object is non-null, dereferenceable by compatible types.<br></div><div><br></div>-Kevin<br><div><div><br><span class="gmail-im"></span></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 9, 2017 at 8:00 PM, Hans Wennborg 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">I am not a language lawyer, but I'll atttempt to answer anyway.<br>
<span class=""><br>
On Mon, Oct 9, 2017 at 2:16 PM, Kreitzer, David L via cfe-dev<br>
<<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br>
</span><span class="">> 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.<br>
<br>
</span>Yes, I believe that's true. If we're dereferencing s on both paths, it<br>
must point to a struct S object, and then loading from any member of<br>
that object should be fine.<br>
<span class=""><br>
> 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>
</span>I suspect it would be within the compiler's rights, but my language<br>
knowledge is too weak. Does the cast imply that s points to a valid<br>
struct S object (or null, but then we couldn't dereference it)? I'm<br>
curious to find out :-)<br>
<br>
- Hans<br>
<div class="HOEnZb"><div class="h5">______________________________<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>
</div></div></blockquote></div><br></div>