http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57264

            Bug ID: 57264
           Summary: cld not emitted when string instructions used, and
                    '-mcld' on command line
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: thutt at vmware dot com

A defect has been found in several versions of gcc with respect to the
'-mcld' option.

  -mcld

     This option instructs GCC to emit a "cld" instruction in the
     prologue of functions that use string instructions.  String
     instructions depend on the DF flag to select between
     autoincrement or autodecrement mode.  While the ABI specifies the
     DF flag to be cleared on function entry, some operating systems
     violate this specification by not clearing the DF flag in their
     exception dispatchers.  The exception handler can be invoked with
     the DF flag set which leads to wrong direction mode, when string
     instructions are used.  This option can be enabled by default on
     32-bit x86 targets by configuring GCC with the --enable-cld
     configure option.  Generation of "cld" instructions can be
     suppressed with the -mno-cld compiler option in this case.


Consider the following distillation of the issue (cld.c):

  void test(int x, int **pp)
  {
      while (x) {
          int *ip = *pp;
          int *op = *pp;
          while (*ip) {
             int v = *ip++;
             *op++ = v + 1;
          }
       }
  }

To demonstrate the issue:

  gcc -c -mcld -O1 -m64 -o cld.o cld.c
  objdump --disassemble --reloc cld.o

An example failure case:

  gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
  Copyright (C) 2011 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions.  There is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


  0000000000000000 <test>:
     0:  85 ff                  test   %edi,%edi
     2:  74 15                  je     19 <test+0x19>
     4:  48 8b 3e               mov    (%rsi),%rdi
     7:  8b 07                  mov    (%rdi),%eax
     9:  85 c0                  test   %eax,%eax
     b:  74 f7                  je     4 <test+0x4>
     d:  83 c0 01               add    $0x1,%eax
    10:  ab                     stos   %eax,%es:(%rdi)
    11:  8b 07                  mov    (%rdi),%eax
    13:  85 c0                  test   %eax,%eax
    15:  74 ed                  je     4 <test+0x4>
    17:  eb f4                  jmp    d <test+0xd>
    19:  f3 c3                  repz retq

For the above sample code, local experimentation has shown than 4.5,
4.6 & 4.7 emit a string instruction without a 'cld' in the prologue.
Versions 4.4 & 4.8 do not emit a string instruction.

Most perturbations to the above sample code will change the output so
that no string instruction is emitted when using the defective
versions.

It is expected that a 'cld' instruction will be generated in the
function prolong whenever any string instruction is emitted by gcc when
the '-mcld' option has been provided.

Reply via email to