[cfe-dev] Speculative load optimization

Hans Wennborg via cfe-dev cfe-dev at lists.llvm.org
Mon Oct 9 17:00:20 PDT 2017


I am not a language lawyer, but I'll atttempt to answer anyway.

On Mon, Oct 9, 2017 at 2:16 PM, Kreitzer, David L via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
> This llvm patch, https://reviews.llvm.org/D37289, 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:
>
>     typedef struct S {
>       char padding[4088];
>       struct S *p1;
>       struct S *p2;
>     } S;
>
>     struct S* f1(struct S *s, int x)
>     {
>       S *r;
>       if (x)
>         r = s->p1;
>       else
>         r = s->p2;
>       return r;
>     }
>
> TO
>
>     struct S* f1(struct S *s, int x)
>     {
>       return (x) ? s->p1 : s->p2;
>     }
>
> The fundamental question seems to be whether loading one member of struct S
> makes it valid to load other members of the same struct.

Yes, I believe that's true. If we're dereferencing s on both paths, it
must point to a struct S object, and then loading from any member of
that object should be fine.

> 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:
>
>     typedef struct T {
>       char padding[4088];
>       struct S *p1;
>     } T;
>
>     struct S* f2(struct S *s, int x)
>     {
>       S *r;
>       if (x)
>         r = ((T*)s)->p1;
>       else
>         r = s->p2;
>       return r;
>     }
>
> Neither compiler will transform this case.

I suspect it would be within the compiler's rights, but my language
knowledge is too weak. Does the cast imply that s points to a valid
struct S object (or null, but then we couldn't dereference it)? I'm
curious to find out :-)

 - Hans



More information about the cfe-dev mailing list