[LLVMbugs] [Bug 4323] New: Tail recursion elimination doesn' t move loads above nounwind readonly call

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Thu Jun 4 06:48:26 PDT 2009


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

           Summary: Tail recursion elimination doesn't move loads above
                    nounwind readonly call
           Product: new-bugs
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: fvbommel at wxs.nl
                CC: llvmbugs at cs.uiuc.edu


Created an attachment (id=3061)
 --> (http://llvm.org/bugs/attachment.cgi?id=3061)
Patch to check CI->mayHaveSideEffects() when looking at a load.

opt -tailcallelim refuses to eliminate a tail call if it's followed by load,
even if the call is both nounwind and readonly.

An example where it would be safe to do this:
----
define fastcc i32 @_D4test3sumFPiiiZi(i32* %a_arg, i32 %a_len_arg, i32
%start_arg) nounwind readonly {
entry:
        %tmp2 = icmp slt i32 %start_arg, %a_len_arg             ; <i1>
[#uses=1]
        br i1 %tmp2, label %else, label %if

if:             ; preds = %entry
        ret i32 0

else:           ; preds = %entry
        %tmp4 = sext i32 %start_arg to i64              ; <i64> [#uses=1]
        %tmp6 = getelementptr i32* %a_arg, i64 %tmp4            ; <i32*>
[#uses=1]
        %tmp10 = add i32 %start_arg, 1          ; <i32> [#uses=1]
        %tmp11 = tail call fastcc i32 @_D4test3sumFPiiiZi(i32* %a_arg, i32
%a_len_arg, i32 %tmp10)              ; <i32> [#uses=1]
        %tmp12 = load i32* %tmp6                ; <i32> [#uses=1]
        %tmp13 = add i32 %tmp12, %tmp11         ; <i32> [#uses=1]
        ret i32 %tmp13
}
----

I'm attaching a small patch that remedies the situation.
Note that I used CI->mayHaveSideEffects() instead of CI->onlyReadsMemory() to
correctly handle the case where the call may throw and the load may introduce
undefined behavior[1]. This way, the transformation does not take place in that
case.


[1]: For example, if the pointer being loaded from may be null but the call
will throw in this case it's not safe to move the load before the call since
that would produce undefined behavior instead of an exception.


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