aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp10
-rw-r--r--test/Transforms/InstCombine/nothrow.ll8
2 files changed, 18 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index c76403e039..527ed43010 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -9578,6 +9578,16 @@ Instruction *InstCombiner::SimplifyMemSet(MemSetInst *MI) {
/// the heavy lifting.
///
Instruction *InstCombiner::visitCallInst(CallInst &CI) {
+ // If the caller function is nounwind, mark the call as nounwind, even if the
+ // callee isn't.
+ if (CI.getParent()->getParent()->doesNotThrow() &&
+ !CI.doesNotThrow()) {
+ CI.setDoesNotThrow();
+ return &CI;
+ }
+
+
+
IntrinsicInst *II = dyn_cast<IntrinsicInst>(&CI);
if (!II) return visitCallSite(&CI);
diff --git a/test/Transforms/InstCombine/nothrow.ll b/test/Transforms/InstCombine/nothrow.ll
new file mode 100644
index 0000000000..fbf162a1db
--- /dev/null
+++ b/test/Transforms/InstCombine/nothrow.ll
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep call
+; rdar://6880732
+declare double @t1(i32) readonly
+
+define void @t2() nounwind {
+ call double @t1(i32 42) ;; dead call even though callee is not nothrow.
+ ret void
+}