Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 5 Jul 2015 09:44:13 +0300
From: Solar Designer <solar@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: Re: extend SIMD intrinsics

On Sun, Jul 05, 2015 at 11:01:48AM +0800, Lei Zhang wrote:
> As x86's vector type is element-type-agnostic, some intrinsics are also type agnostic, e.g. _mm_load_si128 & _mm_and_si128, which can be used for whatever types of integer vectors. However, AltiVec strictly distinguishes among different vector types. To load a 'vector int' from memory, you must pass a 'int*' pointer to vec_ld(); 'void*' or any other types of pointer would trigger a compile error. This means, like we divide vtype into vtype32 and vtype64, we may have to divide vload into vload_epi32 and vload_epi64, and other intrinsics alike.
> 
> I took a look at ARM's NEON intrinsics, which, like AltiVec, also  distinguishes among different vector types. So a element-type-aware interface of pseudo-intrinsics may be more generally applicable.

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.

The explicit load/store intrinsics are useful when we'd be using
specialized kinds of them (e.g., non-temporal loads and stores, in
rare cases where those are preferable), but not when we merely want to
access the data in the compiler's default way.

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.
Unfortunately, I am not aware of any reliable information on this.
Obviously, intrinsics are not mentioned in C standard documents.  Maybe
their relationship with strict aliasing is explained in some compilers'
documentation or such, but so far I haven't seen anything of this sort.

So I think it's safer for us to assume that C strict aliasing rules
apply either way.  This means we should avoid typecasts and prefer using
the correct SIMD types right away, or if we actually need to access the
same data via different types (e.g., SIMD and scalar), then use unions.

(And yes, my bitslice DES code currently violates that.  And it does use
the load/store intrinsics, which might or might not make it safe.
Luckily, this is just a password cracker, and we have the self-test, so
the worst that is likely to happen is a build that would refuse to run.
In theory, though, a C compiler could generate any malicious code or
whatever, if it considers this UB despite of the use of intrinsics.
So ideally I should fix this at some point.)

Alexander

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ