[LLVMbugs] [Bug 7272] New: Bad interaction between byval, -tailcallelim, -inline and -dse

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon May 31 11:12:18 PDT 2010


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

           Summary: Bad interaction between byval, -tailcallelim, -inline
                    and -dse
           Product: new-bugs
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: baldrick at free.fr
                CC: llvmbugs at cs.uiuc.edu


Consider the following testcase (note the byval on @bar's parameter):

target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"
declare void @ext(i32*)
define void @bar(i32* byval %x) {
  call void @ext(i32* %x)
  ret void
}
define void @foo(i32* %x) { 
  call void @bar(i32* byval %x)
  ret void
}

Running it through "opt -tailcallelim", marks the @bar call as being a tail
call:

define void @foo(i32* %x) {
  tail call void @bar(i32* byval %x)
  ret void
}

Now run it through "opt -inline -instcombine" (instcombine to clean up a bit):

define void @foo(i32* %x) {
  %x1 = alloca i32, align 4                       ; <i32*> [#uses=2]
  %1 = load i32* %x, align 1                      ; <i32> [#uses=1]
  store i32 %1, i32* %x1
  tail call void @ext(i32* %x1)
  ret void
}

Now apply "opt -dse":

define void @foo(i32* %x) {
  %x1 = alloca i32, align 4                       ; <i32*> [#uses=1]
  tail call void @ext(i32* %x1)
  ret void
}

Note how an uninitialized variable is now passed in the call to @ext, while
originally it was the a variable initialized to whatever value %x points to.

This is the cause of a miscompilation of LLVM by dragonegg on x86-32.

Personally I think the right thing to do is to not have tailcallelim mark
calls as tail calls if they have a byval parameter.  That's because byval
is equivalent to declaring a stack variable and doing a copy, so amounts
to the use of caller's stack (you could argue that logically the copy
could be considered to be done in the callees stack; in that case the call
to @ext in @bar should not have been marked tail call).

However another possibility is to have the inliner clear tail call flags
when there is a byval parameter.

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