diff --git a/lib/LLVMPasses/LLVMMergeFunctions.cpp b/lib/LLVMPasses/LLVMMergeFunctions.cpp index 25b4d3f61b220..07734c20e2166 100644 --- a/lib/LLVMPasses/LLVMMergeFunctions.cpp +++ b/lib/LLVMPasses/LLVMMergeFunctions.cpp @@ -1188,6 +1188,9 @@ void SwiftMergeFunctions::removeEquivalenceClassFromTree(FunctionEntry *FE) { // Selects proper bitcast operation, // but a bit simpler then CastInst::getCastOpcode. static Value *createCast(IRBuilder<> &Builder, Value *V, Type *DestTy) { + if (V->getType() == DestTy) + return V; + Type *SrcTy = V->getType(); if (SrcTy->isStructTy()) { assert(DestTy->isStructTy()); @@ -1357,7 +1360,8 @@ bool SwiftMergeFunctions::replaceDirectCallers(Function *Old, Function *New, NewArgAttrs); newAttrList = fixUpTypesInByValAndStructRetAttributes(FType, newAttrList); NewCI->setAttributes(newAttrList); - CI->replaceAllUsesWith(NewCI); + Value *retVal = createCast(Builder, NewCI, CI->getType()); + CI->replaceAllUsesWith(retVal); CI->eraseFromParent(); } assert(Old->use_empty() && "should have replaced all uses of old function"); diff --git a/test/LLVMPasses/merge_func_opaque_pointers.ll b/test/LLVMPasses/merge_func_opaque_pointers.ll new file mode 100644 index 0000000000000..7165fc5b32fad --- /dev/null +++ b/test/LLVMPasses/merge_func_opaque_pointers.ll @@ -0,0 +1,34 @@ +; RUN: %swift-llvm-opt -swift-merge-functions -swiftmergefunc-threshold=4 -opaque-pointers %s | %FileCheck %s + +; REQUIRES: PTRSIZE=64 + +@g1 = external global i32 + +define internal i64 @return_0(i32 %x, i32 %y) { + %sum = add i32 %x, %y + %sum2 = add i32 %sum, %y + %l = load i32, i32* @g1, align 4 + %sum3 = add i32 %sum2, %y + ret i64 0 +} + +define internal ptr @return_null(i32 %x, i32 %y) { + %sum = add i32 %x, %y + %sum2 = add i32 %sum, %y + %l = load i32, i32* @g1, align 4 + %sum3 = add i32 %sum2, %y + ret ptr null +} + +declare void @take_results(i64, ptr) + + +; CHECK-LABEL: define void @call_return_null +; CHECK: %1 = call i64 @return_0Tm(i32 0, i32 0) +; CHECK: %2 = call ptr @return_0Tm(i32 0, i32 0) +define void @call_return_null() { + %r1 = call i64 @return_0(i32 0, i32 0) + %r2 = call ptr @return_null(i32 0, i32 0) + call void @take_results(i64 %r1, ptr %r2) + ret void +}