Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 6 Jul 2015 11:23:55 +0300
From: Solar Designer <>
Subject: Re: extend SIMD intrinsics

On Mon, Jul 06, 2015 at 09:43:43AM +0200, magnum wrote:
> On 2015-07-06 04:24, Lei Zhang wrote:
> >>On Jul 5, 2015, at 2:44 PM, Solar Designer <> wrote:
> >>While in general you're right, for loads and stores in particular an
> >>alternative approach may be to stop using those intrinsics, and instead
> >>use simple assignments (or nothing at all, within expressions) at the C
> >>level.  I don't know whether this will result in any worse code being
> >>generated on any relevant arch; I think I haven't run into such cases so
> >>far.  For example, in yescrypt-simd.c, I am not using any load/store
> >>intrinsics, and the generated code is good.
> >
> >That makes sense. I think compilers should have no difficulty
> >converting a vector assignment into a proper vector load/store. But
> >code written this way may look a bit messier, when pointer
> >dereferencing is involved, e.g.
> >
> >void func(uint32_t *buf) {
> >     vtype32 v = *((vtype32*)buf); // could be vload(buf)
> >     ...
> >}
> You could do just the typecast in a 'vload' pseudo-intrinsic:
> #define vload(buf) *((vtype32*)buf)
> OTOH you could do that with a load/store intrinsics too:
> #define vload(buf) _real_intrinsic((vtype32*)buf)

Yes, and all of these, including Lei's example, violate strict aliasing
rules - unless possibly there's some arch-specific standard saying that
it's OK to alias vectors and their elements (I am not aware of such
exceptions being specified anywhere).

> >>Now, there might or might not be a difference as it relates to C strict
> >>aliasing rules.  Maybe the load/store intrinsics allow us to perform
> >>an equivalent of typecasts yet safely circumvent C strict aliasing rules.
> >
> >If I understand the strict aliasing rule correctly, I don't see how
> >the current use of intrinsics in JtR could violate the rule, as we
> >don't use different vector types to access the same memory address.
> We currently declare the functions like this:
> void SSESHA256body(vtype *data, ARCH_WORD_32 *out, ARCH_WORD_32 
> *reload_state, unsigned SSEi_flags);
> I think we break strict aliasing rules right there: reload_state, when 
> used, is an alias to either data or out but they are declared as 
> different types.

It certainly sounds so from your description.

> I'm not sure why they are declared like this. Since all three really are 
> vectors, I think we should have it as:
> void SSESHA256body(vtype32 *data, vtype32 *out, vtype32 *reload_state, 
> uint32_t SSEi_flags);
> Note also that in sse-intrinsics.h the functions are *externally* 
> declared with "vtype" being a macro defined as "void". I'm not sure who 
> made it that way originally nor if it's 100% kosher, but it sure is 
> convenient.

Sounds like another instance of undefined behavior.

Regarding possible use of union types, here's a relevant posting by
Alexander Cherepanov:

Nearby postings in this thread are also relevant.


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.