public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/58735] New: X86_64 sign extend on unsigned values
@ 2013-10-15 9:33 steffen-schmidt at siemens dot com
2013-10-15 9:35 ` [Bug target/58735] " steffen-schmidt at siemens dot com
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: steffen-schmidt at siemens dot com @ 2013-10-15 9:33 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58735
Bug ID: 58735
Summary: X86_64 sign extend on unsigned values
Product: gcc
Version: 4.8.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: steffen-schmidt at siemens dot com
Created attachment 31009
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31009&action=edit
Example functions
The target is x86_64-pc-elf or x86_64-pc-linux-gnu (for both -m64 or -mx32)
This example function defines some unsigned global variables of different size.
During the bit shift operation the compiler needs to extend the small size
unsigned values of 8bit and 32bit into a 64bit unsiged.
When specifying an explicit cast to 64bit unsigned, the resulting code is
correct (see shift_and_cast()). Without the explicit cast, however, the
compiler sign-extends from 32bit to 64bit, which generates the wrong result
(see shift()) .
#if (LONG_BIT == 64)
typedef unsigned long int uint64_t;
#else
typedef unsigned long long uint64_t;
#endif
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
volatile uint64_t sres;
volatile uint8_t sval;
volatile uint32_t scnt;
void shift()
{
sres = 0;
sval = 0xaa;
scnt = 24;
sres |= sval << scnt;
}
void shift_and_cast()
{
sres = 0;
sval = 0xaa;
scnt = 24;
sres |= (uint64_t)sval << scnt;
}
Here is the assembly:
shift:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq $0, sres(%rip)
movb $-86, sval(%rip)
movl $24, scnt(%rip)
movzbl sval(%rip), %eax
movzbl %al, %edx
movl scnt(%rip), %eax
movl %eax, %ecx
sall %cl, %edx
movl %edx, %eax
# Here the sign extension happens:
movslq %eax, %rdx
movq sres(%rip), %rax
orq %rdx, %rax
movq %rax, sres(%rip)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
shift_and_cast:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq $0, sres(%rip)
movb $-86, sval(%rip)
movl $24, scnt(%rip)
movzbl sval(%rip), %eax
movzbl %al, %edx
movl scnt(%rip), %eax
movl %eax, %ecx
salq %cl, %rdx
# no sign extension:
movq sres(%rip), %rax
orq %rdx, %rax
movq %rax, sres(%rip)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
We're always handling unsigned variables, so it's not quite clear, why an
explicit cast should be necessary to produce the correct code.
Example was comiled with:
x86_64_gcc_pc_elf_4.8.1\bin\x86_64-pc-elf-gcc.exe -r -c -nostdlib test.c -o
test.o -save-temps -O0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug target/58735] X86_64 sign extend on unsigned values
2013-10-15 9:33 [Bug target/58735] New: X86_64 sign extend on unsigned values steffen-schmidt at siemens dot com
@ 2013-10-15 9:35 ` steffen-schmidt at siemens dot com
2013-10-15 9:45 ` jakub at gcc dot gnu.org
2013-10-15 10:51 ` mpolacek at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: steffen-schmidt at siemens dot com @ 2013-10-15 9:35 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58735
--- Comment #1 from Steffen Schmidt <steffen-schmidt at siemens dot com> ---
Created attachment 31010
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31010&action=edit
Assembly
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug target/58735] X86_64 sign extend on unsigned values
2013-10-15 9:33 [Bug target/58735] New: X86_64 sign extend on unsigned values steffen-schmidt at siemens dot com
2013-10-15 9:35 ` [Bug target/58735] " steffen-schmidt at siemens dot com
@ 2013-10-15 9:45 ` jakub at gcc dot gnu.org
2013-10-15 10:51 ` mpolacek at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: jakub at gcc dot gnu.org @ 2013-10-15 9:45 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58735
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
There is nothing wrong about it, just your expectations.
sval << scnt
is due to C/C++ integral promotions performed as ((int) sval) << scnt,
depending on the exact standard for 32-bit int is either undefined behavior or
-1442840576
and that is then extended to 64-bit type.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Bug target/58735] X86_64 sign extend on unsigned values
2013-10-15 9:33 [Bug target/58735] New: X86_64 sign extend on unsigned values steffen-schmidt at siemens dot com
2013-10-15 9:35 ` [Bug target/58735] " steffen-schmidt at siemens dot com
2013-10-15 9:45 ` jakub at gcc dot gnu.org
@ 2013-10-15 10:51 ` mpolacek at gcc dot gnu.org
2 siblings, 0 replies; 4+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2013-10-15 10:51 UTC (permalink / raw)
To: gcc-bugs
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58735
Marek Polacek <mpolacek at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
CC| |mpolacek at gcc dot gnu.org
Resolution|--- |INVALID
--- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Invalid then.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-10-15 10:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-15 9:33 [Bug target/58735] New: X86_64 sign extend on unsigned values steffen-schmidt at siemens dot com
2013-10-15 9:35 ` [Bug target/58735] " steffen-schmidt at siemens dot com
2013-10-15 9:45 ` jakub at gcc dot gnu.org
2013-10-15 10:51 ` mpolacek at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).