[PATCH] Fix inliner to not inline functions that call setjmp() using "invoke"

Mark Seaborn mseaborn at chromium.org
Wed Dec 11 17:33:50 PST 2013


Hi chandlerc,

Fix inliner to not inline functions that call setjmp() using "invoke"

This fixes PR18206.

This fixes a correctness problem but isn't ideal.  InlineCost seems to
ignore invoke instructions generally, so IsRecursiveCall doesn't get
set for invokes.

A simpler fix would be to change analyzeBlock()'s loop to iterate to
BB->end() instead of llvm::prior(BB->end()), but that causes two tests
to fail (alloca-bonus.ll and ptr-diff.ll), and I don't understand the
code well enough to know what other effects it might have.  Any
suggestions here?


http://llvm-reviews.chandlerc.com/D2390

Files:
  lib/Analysis/IPA/InlineCost.cpp
  test/Transforms/Inline/inline_returns_twice_invoke.ll

Index: lib/Analysis/IPA/InlineCost.cpp
===================================================================
--- lib/Analysis/IPA/InlineCost.cpp
+++ lib/Analysis/IPA/InlineCost.cpp
@@ -848,6 +848,18 @@
       return false;
   }
 
+  // Check the terminator instruction specially because the previous
+  // loop skips it.
+  if (InvokeInst *Invoke = dyn_cast<InvokeInst>(BB->getTerminator())) {
+    if (Invoke->hasFnAttr(Attribute::ReturnsTwice) &&
+        !F.getAttributes().hasAttribute(AttributeSet::FunctionIndex,
+                                        Attribute::ReturnsTwice)) {
+      // This aborts the entire analysis.
+      ExposesReturnsTwice = true;
+      return false;
+    }
+  }
+
   return true;
 }
 
Index: test/Transforms/Inline/inline_returns_twice_invoke.ll
===================================================================
--- /dev/null
+++ test/Transforms/Inline/inline_returns_twice_invoke.ll
@@ -0,0 +1,43 @@
+; RUN: opt %s -inline -S | FileCheck %s
+
+; Check that functions with "returns_twice" invokes are only inlined
+; if they are themselves marked as "returns_twice".  This is a
+; regression test for PR18206.
+
+declare void @maybe_setjmp()
+
+
+define internal void @inner() {
+  invoke void @maybe_setjmp() returns_twice
+      to label %cont unwind label %lpad
+cont:
+  ret void
+lpad:
+  %lp = landingpad i32 personality i8* null cleanup
+  resume i32 %lp
+}
+
+define void @outer() {
+  call void @inner()
+  ret void
+}
+; CHECK: define void @outer()
+; CHECK-NEXT: call void @inner()
+
+
+define internal void @inner_returns_twice() returns_twice {
+  invoke void @maybe_setjmp() returns_twice
+      to label %cont unwind label %lpad
+cont:
+  ret void
+lpad:
+  %lp = landingpad i32 personality i8* null cleanup
+  resume i32 %lp
+}
+
+define void @outer2() {
+  call void @inner_returns_twice()
+  ret void
+}
+; CHECK: define void @outer2()
+; CHECK-NEXT: invoke void @maybe_setjmp()
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2390.1.patch
Type: text/x-patch
Size: 1934 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131211/9ddb1620/attachment.bin>


More information about the llvm-commits mailing list