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).