[cfe-dev] Speculative load optimization
Kevin Choi via cfe-dev
cfe-dev at lists.llvm.org
Mon Oct 9 20:21:48 PDT 2017
I suspect
> r = ((T*)s)->p1;
Is allowed under C99 ยง6.5, strict aliasing rule
An object shall have its stored value accessed only by an lvalue expression
that has one of the following types
...
- 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)
CMIIW, the cmov optimizer may be pessimistic here -- access to one path
implies object is non-null, dereferenceable by compatible types.
-Kevin
On Mon, Oct 9, 2017 at 8:00 PM, Hans Wennborg via cfe-dev <
cfe-dev at lists.llvm.org> wrote:
> 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
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171009/ae122aad/attachment.html>
More information about the cfe-dev
mailing list