Skip to content

Commit

Permalink
MAINT: check alignment of copy arguments in debug mode
Browse files Browse the repository at this point in the history
Allows catching unaligned access issues on x86.
Triggers TestRegression.test_complex64_alignment if the fix is reverted.

Also remove some dead code.
  • Loading branch information
juliantaylor committed Sep 24, 2013
1 parent 0a38962 commit 848949a
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions numpy/core/src/multiarray/lowlevel_strided_loops.c.src
Expand Up @@ -20,6 +20,17 @@


#include "lowlevel_strided_loops.h" #include "lowlevel_strided_loops.h"


/* used for some alignment checks */
#define _ALIGN(type) offsetof(struct {char c; type v;}, v)
/*
* Disable harmless compiler warning "4116: unnamed type definition in
* parentheses" which is caused by the _ALIGN macro.
*/
#if defined(_MSC_VER)
#pragma warning(disable:4116)
#endif


/* /*
* x86 platform works with unaligned access but the compiler is allowed to * x86 platform works with unaligned access but the compiler is allowed to
* assume all data is aligned to its size by the C standard. This means it can * assume all data is aligned to its size by the C standard. This means it can
Expand Down Expand Up @@ -118,6 +129,11 @@ static void
npy_intp N, npy_intp NPY_UNUSED(src_itemsize), npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
NpyAuxData *NPY_UNUSED(data)) NpyAuxData *NPY_UNUSED(data))
{ {
#if @is_aligned@ && @elsize@ != 16
/* sanity check */
assert(npy_is_aligned(dst, _ALIGN(@type@)));
assert(npy_is_aligned(src, _ALIGN(@type@)));
#endif
/*printf("fn @prefix@_@oper@_size@elsize@\n");*/ /*printf("fn @prefix@_@oper@_size@elsize@\n");*/
while (N > 0) { while (N > 0) {
#if @is_aligned@ #if @is_aligned@
Expand Down Expand Up @@ -182,6 +198,11 @@ static void
npy_intp N, npy_intp NPY_UNUSED(src_itemsize), npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
NpyAuxData *NPY_UNUSED(data)) NpyAuxData *NPY_UNUSED(data))
{ {
#if @is_aligned@ && @elsize@ != 16
/* sanity check */
assert(npy_is_aligned(dst, _ALIGN(@type@)));
assert(npy_is_aligned(src, _ALIGN(@type@)));
#endif
#if @elsize@ == 1 && @dst_contig@ #if @elsize@ == 1 && @dst_contig@
memset(dst, *src, N); memset(dst, *src, N);
#else #else
Expand Down Expand Up @@ -785,15 +806,23 @@ static void
_TYPE2 dst_value; _TYPE2 dst_value;
#endif #endif


#if @aligned@
/* sanity check */
# if !@is_complex1@
assert(npy_is_aligned(src, _ALIGN(_TYPE1)));
# endif
# if !@is_complex2@
assert(npy_is_aligned(dst, _ALIGN(_TYPE2)));
# endif
#endif

/*printf("@prefix@_cast_@name1@_to_@name2@\n");*/ /*printf("@prefix@_cast_@name1@_to_@name2@\n");*/


while (N--) { while (N--) {
#if @aligned@ #if @aligned@
# if @is_complex1@ # if @is_complex1@
src_value[0] = ((_TYPE1 *)src)[0]; src_value[0] = ((_TYPE1 *)src)[0];
src_value[1] = ((_TYPE1 *)src)[1]; src_value[1] = ((_TYPE1 *)src)[1];
# elif !@aligned@
src_value = *((_TYPE1 *)src);
# endif # endif
#else #else
memmove(&src_value, src, sizeof(src_value)); memmove(&src_value, src, sizeof(src_value));
Expand Down Expand Up @@ -836,8 +865,6 @@ static void
# if @is_complex2@ # if @is_complex2@
((_TYPE2 *)dst)[0] = dst_value[0]; ((_TYPE2 *)dst)[0] = dst_value[0];
((_TYPE2 *)dst)[1] = dst_value[1]; ((_TYPE2 *)dst)[1] = dst_value[1];
# elif !@aligned@
*((_TYPE2 *)dst) = dst_value;
# endif # endif
#else #else
memmove(dst, &dst_value, sizeof(dst_value)); memmove(dst, &dst_value, sizeof(dst_value));
Expand Down

0 comments on commit 848949a

Please sign in to comment.