diff --git a/lib/Analysis/IPA/InlineCost.cpp b/lib/Analysis/IPA/InlineCost.cpp index 46cba8adecb..453658386d7 100644 --- a/lib/Analysis/IPA/InlineCost.cpp +++ b/lib/Analysis/IPA/InlineCost.cpp @@ -713,7 +713,7 @@ bool CallAnalyzer::simplifyCallSite(Function *F, CallSite CS) { } bool CallAnalyzer::visitCallSite(CallSite CS) { - if (CS.isCall() && cast(CS.getInstruction())->canReturnTwice() && + if (CS.hasFnAttr(Attribute::ReturnsTwice) && !F.getAttributes().hasAttribute(AttributeSet::FunctionIndex, Attribute::ReturnsTwice)) { // This aborts the entire analysis. diff --git a/test/Transforms/Inline/inline_returns_twice.ll b/test/Transforms/Inline/inline_returns_twice.ll index 6dfd1c72e2c..36042640cc0 100644 --- a/test/Transforms/Inline/inline_returns_twice.ll +++ b/test/Transforms/Inline/inline_returns_twice.ll @@ -4,38 +4,81 @@ ; if they are themselves marked as such. declare i32 @a() returns_twice -declare i32 @b() returns_twice -define i32 @f() { +define i32 @inner1() { entry: %call = call i32 @a() returns_twice %add = add nsw i32 1, %call ret i32 %add } -define i32 @g() { +define i32 @outer1() { entry: -; CHECK-LABEL: define i32 @g( -; CHECK: call i32 @f() -; CHECK-NOT: call i32 @a() - %call = call i32 @f() +; CHECK-LABEL: define i32 @outer1( +; CHECK: call i32 @inner1() + %call = call i32 @inner1() %add = add nsw i32 1, %call ret i32 %add } -define i32 @h() returns_twice { +define i32 @inner2() returns_twice { entry: - %call = call i32 @b() returns_twice + %call = call i32 @a() returns_twice %add = add nsw i32 1, %call ret i32 %add } -define i32 @i() { +define i32 @outer2() { entry: -; CHECK-LABEL: define i32 @i( -; CHECK: call i32 @b() -; CHECK-NOT: call i32 @h() - %call = call i32 @h() returns_twice +; CHECK-LABEL: define i32 @outer2( +; CHECK: call i32 @a() + %call = call i32 @inner2() returns_twice + %add = add nsw i32 1, %call + ret i32 %add +} + +define i32 @inner3() { +entry: + %invoke = invoke i32 @a() returns_twice + to label %cont unwind label %lpad + +cont: + %add = add nsw i32 1, %invoke + ret i32 %add + +lpad: + %lp = landingpad i32 personality i8* null cleanup + resume i32 %lp +} + +define i32 @outer3() { +entry: +; CHECK-LABEL: define i32 @outer3( +; CHECK: call i32 @inner3() + %call = call i32 @inner3() + %add = add nsw i32 1, %call + ret i32 %add +} + +define i32 @inner4() returns_twice { +entry: + %invoke = invoke i32 @a() returns_twice + to label %cont unwind label %lpad + +cont: + %add = add nsw i32 1, %invoke + ret i32 %add + +lpad: + %lp = landingpad i32 personality i8* null cleanup + resume i32 %lp +} + +define i32 @outer4() { +entry: +; CHECK-LABEL: define i32 @outer4( +; CHECK: invoke i32 @a() + %call = call i32 @inner4() returns_twice %add = add nsw i32 1, %call ret i32 %add }