[LLVMbugs] [Bug 11768] New: __sync_synchronize non-sse lowering doesn't clobber flags

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Jan 16 05:49:18 PST 2012


http://llvm.org/bugs/show_bug.cgi?id=11768

             Bug #: 11768
           Summary: __sync_synchronize non-sse lowering doesn't clobber
                    flags
           Product: new-bugs
           Version: trunk
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: dimitry at andric.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


While building icu with clang trunk r148116 on FreeBSD/i386, I ran into
several crashes when the build-time tool 'genrb' was run.  This was
caused by multiple problems in code generation.  After some reducing,
one of them turned out to be with __sync_synchronize().

Take the following sample, much reduced from the icu testcase:

  extern void *ptr;

  void foo();
  void bar();

  void baz(void)
  {
    int flag = (ptr == (void*)0);
    __sync_synchronize();
    if (flag)
      foo();
    else
      bar();
  }

This is compiled with clang -O2 -S, giving (on i386):

  baz:                                    # @baz
  # BB#0:                                 # %entry
      xorl    %eax, %eax
      cmpl    $0, ptr
      lock
      orl     %eax, (%esp)
      jne     .LBB0_2
  # BB#1:                                 # %if.then
      jmp     foo                     # TAILCALL
  .LBB0_2:                                # %if.else
      jmp     bar                     # TAILCALL

So 'jne' is done, incorrectly assuming 'lock orl' didn't clobber the
flags.  Compare this to the amd64 version:

  baz:                                    # @baz
      .cfi_startproc
  # BB#0:                                 # %entry
      movq    ptr(%rip), %rax
      mfence
      testq   %rax, %rax
      jne     .LBB0_2
  # BB#1:                                 # %if.then
      xorb    %al, %al
      jmp     foo                     # TAILCALL
  .LBB0_2:                                # %if.else
      xorb    %al, %al
      jmp     bar                     # TAILCALL

Here, 'testq' is executed *after* 'mfence', as it should.  Another
comparison is with gcc 4.6 on i386:

  baz:
  .LFB0:
      .cfi_startproc
      movl    ptr, %eax
      lock orl        $0, (%esp)
      testl   %eax, %eax
      je      .L4
      jmp     bar
      .p2align 4,,7
  .L4:
      jmp     foo
      .cfi_endproc

Here, it also compares after 'lock orl'.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list