[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