(perl #133495) remove probing for d_u32align
authorTony Cook <tony@develop-help.com>
Mon, 7 Oct 2019 23:41:46 +0000 (10:41 +1100)
committerTony Cook <tony@develop-help.com>
Tue, 8 Oct 2019 04:06:25 +0000 (15:06 +1100)
Compiler optimisation meant the could return the wrong result in some
cases.

This wasn't a problem on x86, but on platforms where alignment is
required it caused problems.

Strangely enough d_u32align is "define" in the win32 config files,
on any x64 system (the probe only checked on 32-bit systems), on
ARM and on the one i386 build I checked.

This should have little to no effect on performance, for example,
building:

typedef unsigned long U64;

U64 b64little(unsigned char *p) {
    return *p | ((U64)p[1] << 8) | ((U64)p[2] << 16) | ((U64)p[3] << 24)
         | ((U64)p[4] << 32) | ((U64)p[5] << 40) | ((U64)p[6] << 48) | ((U64)p[7] << 56);
}

U64 b64big(unsigned char *p) {
    return ((U64)*p << 56) | ((U64)p[1] << 48) | ((U64)p[2] << 40) | ((U64)p[3] << 32)
         | ((U64)p[4] << 24) | ((U64)p[5] << 16) | ((U64)p[6] << 8) | ((U64)p[7]);
}

unsigned b32little(unsigned char *p) {
    return *p | ((unsigned)p[1] << 8) | ((unsigned)p[2] << 16) | ((unsigned)p[3] << 24);
}

unsigned b32big(unsigned char *p) {
    return ((unsigned)p[0] << 24) | ((unsigned)p[1] << 16) | ((unsigned)p[2] << 8) | p[3];
}

with:

gcc -O2 -S test.c

produces:

.file "test.c"
.text
.p2align 4,,15
.globl b64little
.type b64little, @function
b64little:
.LFB0:
.cfi_startproc
movq (%rdi), %rax
ret
.cfi_endproc
.LFE0:
.size b64little, .-b64little
.p2align 4,,15
.globl b64big
.type b64big, @function
b64big:
.LFB1:
.cfi_startproc
movq (%rdi), %rax
bswap %rax
ret
.cfi_endproc
.LFE1:
.size b64big, .-b64big
.p2align 4,,15
.globl b32little
.type b32little, @function
b32little:
.LFB2:
.cfi_startproc
movl (%rdi), %eax
ret
.cfi_endproc
.LFE2:
.size b32little, .-b32little
.p2align 4,,15
.globl b32big
.type b32big, @function
b32big:
.LFB3:
.cfi_startproc
movl (%rdi), %eax
bswap %eax
ret
.cfi_endproc
.LFE3:
.size b32big, .-b32big
.ident "GCC: (Debian 6.3.0-18+deb9u1) 6.3.0 20170516"
.section .note.GNU-stack,"",@progbits

so the compiler is smart enough to recognize the unaligned access code
and optimize it on platforms that support it.

MSVC doesn't seem to optimize this, but since Win32 has been built
with d_u32align=define since 2005, this change will make no
difference.

Configure

index cde374b..fad1c9f 100755 (executable)
--- a/Configure
+++ b/Configure
        ;;
 esac
 
-: Checking 32bit alignedness
 $cat <<EOM
 
 Checking to see whether you can access character data unalignedly...
-EOM
-case "$d_u32align" in
-'')   $cat >try.c <<EOCP
-#include <stdio.h>
-#$i_stdlib I_STDLIB
-#ifdef I_STDLIB
-#include <stdlib.h>
-#endif
-#define U32 $u32type
-#define BYTEORDER 0x$byteorder
-#define U8 $u8type
-#include <signal.h>
-#ifdef SIGBUS
-$signal_t bletch(int s) { exit(4); }
-#endif
-int main() {
-#if BYTEORDER == 0x1234 || BYTEORDER == 0x4321
-    volatile U8 buf[8];
-    volatile U32 *up;
-    int i;
-
-    if (sizeof(U32) != 4) {
-       printf("sizeof(U32) is not 4, but %d\n", sizeof(U32));
-       exit(1);
-    }
-
-    fflush(stdout);
-
-#ifdef SIGBUS
-    signal(SIGBUS, bletch);
-#endif
-
-    buf[0] = 0;
-    buf[1] = 0;
-    buf[2] = 0;
-    buf[3] = 1;
-    buf[4] = 0;
-    buf[5] = 0;
-    buf[6] = 0;
-    buf[7] = 1;
-
-    for (i = 0; i < 4; i++) {
-       up = (U32*)(buf + i);
-       if (! ((*up == 1 << (8*i)) ||   /* big-endian */
-              (*up == 1 << (8*(3-i)))  /* little-endian */
-             )
-          )
-       {
-           printf("read failed (%x)\n", *up);
-           exit(2);
-       }
-    }
-
-    /* write test */
-    for (i = 0; i < 4; i++) {
-       up = (U32*)(buf + i);
-       *up = 0xBeef;
-       if (*up != 0xBeef) {
-           printf("write failed (%x)\n", *up);
-           exit(3);
-       }
-    }
 
-    exit(0);
-#else
-    printf("1\n");
-    exit(1);
-#endif
-    return 0;
-}
-EOCP
-set try
-if eval $compile_ok; then
-       echo "(Testing for character data alignment may crash the test.  That's okay.)" >&4
-       $run ./try 2>&1 >/dev/null
-       case "$?" in
-       0)      cat >&4 <<EOM
-You can access character data pretty unalignedly.
-EOM
-               d_u32align="$undef"
-               ;;
-       *)      cat >&4 <<EOM
-It seems that you must access character data in an aligned manner.
+We assume only aligned access is permitted.
 EOM
-               d_u32align="$define"
-               ;;
-       esac
-else
-       rp='Can you access character data at unaligned addresses?'
-       dflt='n'
-       . ./myread
-       case "$ans" in
-       [yY]*)  d_u32align="$undef"  ;;
-       *)      d_u32align="$define" ;;
-       esac
-fi
-$rm_try
-;;
+: Checking 32bit alignedness
+: We no longer check and assume it is required.
+case "$d_u32align" in
+'') d_u32align="$define" ;;
 esac
 
 : see if ualarm exists