aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp5
-rw-r--r--test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll15
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp
index 792fa980a6..4ebdaf3fb2 100644
--- a/lib/Transforms/IPO/IPConstantPropagation.cpp
+++ b/lib/Transforms/IPO/IPConstantPropagation.cpp
@@ -147,6 +147,11 @@ bool IPCP::PropagateConstantReturn(Function &F) {
if (F.getReturnType() == Type::VoidTy)
return false; // No return value.
+ // If this function could be overridden later in the link stage, we can't
+ // propagate information about its results into callers.
+ if (F.hasLinkOnceLinkage() || F.hasWeakLinkage())
+ return false;
+
// Check to see if this function returns a constant.
SmallVector<Value *,4> RetVals;
const StructType *STy = dyn_cast<StructType>(F.getReturnType());
diff --git a/test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll b/test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll
new file mode 100644
index 0000000000..fc7e3bba38
--- /dev/null
+++ b/test/Transforms/IPConstantProp/2008-06-09-WeakProp.ll
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | opt -ipconstprop | llvm-dis | grep {ret i32 %r}
+; Should not propagate the result of a weak function.
+; PR2411
+
+define weak i32 @foo() nounwind {
+entry:
+ ret i32 1
+}
+
+define i32 @main() nounwind {
+entry:
+ %r = call i32 @foo( ) nounwind
+ ret i32 %r
+}
+