[LLVMbugs] [Bug 12656] New: restrict keyword can lead to too aggressive optimization

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Wed Apr 25 11:29:31 PDT 2012


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

             Bug #: 12656
           Summary: restrict keyword can lead to too aggressive
                    optimization
           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


Consider the following program, much reduced from FreeBSD's vfscanf()
implementation:

  #include <stdio.h>

  static int suppress;

  void func(int * __restrict p)
  {
    printf("p=%p vs. &suppress=%p\n", p, &suppress);

    if (p == &suppress)
      printf("p == &suppress\n");
    else
      printf("p != &suppress -> WRONG\n");
  }

  int main(void)
  {
    func(&suppress);

    return (0);
  }

Clang (branches/release_31 r155231), with -O1 or higher, optimizes the
first branch of the if statement completely away:

  func:                                   # @func
  # BB#0:                                 # %entry
          pushl   %ebp
          movl    %esp, %ebp
          subl    $24, %esp
          movl    8(%ebp), %eax
          movl    %eax, 4(%esp)
          movl    $suppress, 8(%esp)
          movl    $.L.str, (%esp)
          calll   printf
          movl    $.Lstr, (%esp)
          calll   puts
          addl    $24, %esp
          popl    %ebp
          ret

In contrast, gcc 4.7.1 does emit the test, and both branches:

  func:
  .LFB1:
          .cfi_startproc
          pushl   %ebx
          .cfi_def_cfa_offset 8
          .cfi_offset 3, -8
          subl    $24, %esp
          .cfi_def_cfa_offset 32
          movl    32(%esp), %ebx
          movl    $suppress, 8(%esp)
          movl    $.LC0, (%esp)
          movl    %ebx, 4(%esp)
          call    printf
          cmpl    $suppress, %ebx
          je      .L5
          movl    $.LC2, 32(%esp)
          addl    $24, %esp
          .cfi_remember_state
          .cfi_def_cfa_offset 8
          popl    %ebx
          .cfi_restore 3
          .cfi_def_cfa_offset 4
          jmp     puts
          .p2align 4,,7
  .L5:
          .cfi_restore_state
          movl    $.LC1, 32(%esp)
          addl    $24, %esp
          .cfi_def_cfa_offset 8
          popl    %ebx
          .cfi_restore 3
          .cfi_def_cfa_offset 4
          jmp     puts
          .cfi_endproc

Asking around a bit on #llvm seemed to lead to the conclusion that clang
is in error here, assuming the comparison can never succeed:

  23:12:36<zygoloid> afaics, the optimization isn't valid
  ...
  23:13:22<jyasskin_w> Yeah, "If L is used to access the value of the
                       object X that it designates, and X is also
                       modified (by any means), then: ... Every other
                       lvalue used to access the value of X shall also
                       have its address based on P. ..." So without a
                       modification, there are no aliasing
                       implications.
  ...
  23:14:42<zygoloid> even if there were a modification... the other
                     lvalue, 'suppress', is not used to access the
                     value of X

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