This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
(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)
commite31f3d3767e7d53f56f4bf96ac71a6e8dcec3e95
tree443b01d91aac4c5a5310344f8f0cf0268ecf3922
parente8864dba80952684bf3afe83438d4eee0c3939a9
(perl #133495) remove probing for d_u32align

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