diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index 354971aeff744..18a1b8351a91f 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -793,7 +793,8 @@ promoteArguments(Function *F, function_ref AARGetter, for (Use &U : F->uses()) { CallBase *CB = dyn_cast(U.getUser()); // Must be a direct call. - if (CB == nullptr || !CB->isCallee(&U)) + if (CB == nullptr || !CB->isCallee(&U) || + CB->getFunctionType() != F->getFunctionType()) return nullptr; // Can't change signature of musttail callee diff --git a/llvm/test/Transforms/ArgumentPromotion/opaque-ptr.ll b/llvm/test/Transforms/ArgumentPromotion/opaque-ptr.ll index 25939bc900b86..70cdf0c36000e 100644 --- a/llvm/test/Transforms/ArgumentPromotion/opaque-ptr.ll +++ b/llvm/test/Transforms/ArgumentPromotion/opaque-ptr.ll @@ -80,3 +80,21 @@ define void @caller_overlap(ptr %p) { call i32 @callee_overlap(ptr %p) ret void } + +; Don't promote calls with function type mismatch. +define void @caller_type_mismatch() { +; CHECK-LABEL: define {{[^@]+}}@caller_type_mismatch() { +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @callee_type_mismatch(ptr null) +; CHECK-NEXT: ret void +; + call i32 @callee_type_mismatch(ptr null) + ret void +} + +define internal void @callee_type_mismatch(ptr %p) { +; CHECK-LABEL: define {{[^@]+}}@callee_type_mismatch +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: ret void +; + ret void +}