[LLVMbugs] [Bug 2498] New: Incorrect optimization

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Thu Jun 26 00:13:42 PDT 2008


           Summary: Incorrect optimization
           Product: new-bugs
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: major
          Priority: P2
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: cristic at stanford.edu
                CC: llvmbugs at cs.uiuc.edu

I found the following bug in the optimizer.  Here's a short contrived example:

/* llvm-opt-bug.c */
static int foo(char *s) {
  if (s[0] == 0 || s[100000] != 0)
    return 0;

  return 1;

int main(int argc, char** argv) {
  return foo(argv[1]);

Note that running this program with an empty string as sole argument should
trigger no errors:

gcc llvm-opt-bug.c
./a.out ""

Compiling w/ LLVM and applying all standard compile-time optimizations (but w/
inlining disabled) produces the following bitcode:

llvm-gcc --emit-llvm -c llvm-opt-bug.c
opt --std-compile-opts --disable-inlining llvm-opt-bug.o -o llvm-opt-bug.opt.o
llvm-dis llvm-opt-bug.opt.o
cat llvm-opt-bug.opt.o.ll

; ModuleID = 'llvm-opt-bug.opt.o'
target datalayout =
target triple = "i386-pc-linux-gnu"

define internal fastcc i32 @foo(i8 %s.val, i8 %s.100000.val) nounwind  {
        %tmp4 = icmp eq i8 %s.val, 0            ; <i1> [#uses=1]
        br i1 %tmp4, label %UnifiedReturnBlock, label %bb

bb:             ; preds = %entry
        %tmp9 = icmp eq i8 %s.100000.val, 0             ; <i1> [#uses=1]
        %retval = zext i1 %tmp9 to i32          ; <i32> [#uses=1]
        ret i32 %retval

UnifiedReturnBlock:             ; preds = %entry
        ret i32 0

define i32 @main(i32 %argc, i8** %argv) nounwind  {
        %tmp2 = getelementptr i8** %argv, i32 1         ; <i8**> [#uses=1]
        %tmp3 = load i8** %tmp2, align 4                ; <i8*> [#uses=2]
        %tmp3.val = load i8* %tmp3              ; <i8> [#uses=1]
        %tmp3.idx = getelementptr i8* %tmp3, i32 100000         ; <i8*>
        %tmp3.idx.val = load i8* %tmp3.idx              ; <i8> [#uses=1]
        %tmp4 = tail call fastcc i32 @foo( i8 %tmp3.val, i8 %tmp3.idx.val )
nounwind            ; <i32> [#uses=1]
        ret i32 %tmp4

Note that the load s[100000] in foo() was incorrectly lifted before the if
statement in foo().   

I'm using llvm-gcc 4.2 and llvm 2.3:

$ llvm-gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../llvm-gcc4.2-2.3.source/configure
--enable-languages=c,c++ --disable-shared --disable-bootstrap
Thread model: posix
gcc version 4.2.1 (Based on Apple Inc. build 5555) (LLVM build 2.3)

$ opt --version
Low Level Virtual Machine (http://llvm.org/):
  llvm version 2.3
  Optimized build with assertions.

Please let me know if you need any additional information.

Thank you,

P.S. I apologize if this is a duplicate report; but it doesn't look my
first report was submitted (browser crashed).

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