[llvm-bugs] [Bug 31278] New: Inliner applies incorrect value mapping for recursive calls

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Dec 5 11:27:34 PST 2016


https://llvm.org/bugs/show_bug.cgi?id=31278

            Bug ID: 31278
           Summary: Inliner applies incorrect value mapping for recursive
                    calls
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: bjoern.boenninghoff at tu-dortmund.de
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

Created attachment 17713
  --> https://llvm.org/bugs/attachment.cgi?id=17713&action=edit
code for simple demo reproducing incorrect inlining

"clang -O3" or "opt -inline" may work incorrectly on recursive functions. I
could narrow down and reproduce this for a simple function:

define void @tryme(i32* %ret, i32 %mode, i32 %val) #0 {
  %1 = icmp ne i32 %mode, 0
  br i1 %1, label %4, label %2

; <label>:2                                       ; preds = %0
  %3 = add nsw i32 %val, 5
  store i32 %3, i32* %ret, align 4
  br label %6

; <label>:4                                       ; preds = %0
  %5 = sub nsw i32 %val, 5
  call void @tryme(i32* %ret, i32 0, i32 %5)
  br label %6

; <label>:6                                       ; preds = %4, %2
  ret void
}

This should store %val + 5 to %ret if %mode == 0, and %val otherwise.

opt -inline will transform this to: 

define void @tryme(i32* %ret, i32 %mode, i32 %val) #0 {
  %1 = icmp ne i32 %mode, 0
  br i1 %1, label %4, label %2

; <label>:2                                       ; preds = %0
  %3 = add nsw i32 %val, 5
  store i32 %3, i32* %ret, align 4
  br label %6

; <label>:4                                       ; preds = %0
  %5 = sub nsw i32 %val, 5
  store i32 %5, i32* %ret, align 4
  br label %6

; <label>:6                                       ; preds = %4, %2
  ret void
}

Notice how the second store now stores %5 = %val - 5 (instead of %val - 5 + 5 =
%val).

Attached you will find some C code that produces above and also breaks with
clang -O3, I assume for the same reason.

I tried to track down the root cause in the inliner, and got to the
per-instruction loop in the PruningFunctionCloner::CloneBlock in
lib/Transforms/Utils/CloneFunction.cpp. Here, %val in %3 of the called function
gets mapped to %5, then %3 is correctly simplified to %val of the caller. It
seems like, as caller and callee are identical, %val is now incorrectly mapped
back to %5, thus %3 in is replaced by %5, not %val. It appears to me as if
currently VMap content is not suitable to distinguish caller and callee
versions of Values and their respective mappings for recursive functions.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20161205/91541e5f/attachment.html>


More information about the llvm-bugs mailing list