[LLVMbugs] [Bug 7933] New: Loop Index Split pass changes semantics of source program

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Wed Aug 18 13:18:46 PDT 2010


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

           Summary: Loop Index Split pass changes semantics of source
                    program
           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: tilmann.scheller at googlemail.com
                CC: llvmbugs at cs.uiuc.edu


Running `clang -O3 -c -S -emit-llvm loop.c -o -|opt -loop-index-split -o
-|llvm-dis' on the following C code:

void bar(void);

void foo(long a, long b, long *c) {
  long i;

  for (i = 0; i < b; ++i) {
    if (i == a) {
      bar();
    }
  }
}

produces this LLVM IR, changing the semantics of the source program:

target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"

define void @foo(i64 %a, i64 %b, i64* nocapture %c) nounwind {
entry:
  %cmp6 = icmp sgt i64 %b, 0                      ; <i1> [#uses=1]
  br i1 %cmp6, label %for.body.preheader, label %for.end

for.body.preheader:                               ; preds = %entry
  br label %for.body

for.body:                                         ; preds = %for.body.preheader
  %lisplit = icmp uge i64 %a, 0                   ; <i1> [#uses=1]
  %lisplit1 = icmp eq i64 %a, %b                  ; <i1> [#uses=1]
  %lisplit2 = and i1 %lisplit, %lisplit1          ; <i1> [#uses=1]
  br i1 %lisplit2, label %if.then, label %for.inc

if.then:                                          ; preds = %for.body
  tail call void @bar() nounwind
  br label %for.inc

for.inc:                                          ; preds = %if.then, %for.body
  br label %for.end.loopexit

for.end.loopexit:                                 ; preds = %for.inc
  br label %for.end

for.end:                                          ; preds = %for.end.loopexit,
%entry
  ret void
}

declare void @bar()

basically the program gets transformed into:

void foo(long a, long b, long *c) {
  if (b > 0 && (a >= 0 && a == b)) {
    bar();
  }
}

The correct transformation should be:

void foo(long a, long b, long *c) {
  if (b > 0 && (a >= 0 && a < b)) {
    bar();
  }
}

>From what I can see, the two integer comparisons are wrong:

  %lisplit1 = icmp eq i64 %a, %b
should be replaced with
  %lisplit1 = icmp slt i64 %a, %b

and

  %lisplit = icmp uge i64 %a, 0
should also become
  %lisplit = icmp sge i64 %a, 0

because long is signed.

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