diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3395,6 +3395,10 @@ if (CallerPAL.hasParamAttr(i, Attribute::SwiftError)) return false; + if (!CallerPAL.hasParamAttr(i, Attribute::ByVal) && + Callee->getAttributes().hasParamAttr(i, Attribute::ByVal)) + return false; // Cannot transform to byval. + // If the parameter is passed as a byval argument, then we have to have a // sized type and the sized type has to have the same size as the old type. if (ParamTy != ActTy && CallerPAL.hasParamAttr(i, Attribute::ByVal)) { diff --git a/llvm/test/LTO/X86/cast-to-byval.ll b/llvm/test/LTO/X86/cast-to-byval.ll new file mode 100644 --- /dev/null +++ b/llvm/test/LTO/X86/cast-to-byval.ll @@ -0,0 +1,33 @@ +; Check that cross-module function calls involving conversion to byval aren't +; inlined. + +; RUN: split-file %s %t +; RUN: llvm-as %t/t1.ll -o %t1 +; RUN: llvm-as %t/t2.ll -o %t2 +; RUN: llvm-lto %t1 %t2 -o %t0 -filetype=asm -save-merged-module -exported-symbol=testFoo +; RUN: llvm-dis -o - %t0.merged.bc | FileCheck %s + + +;--- t1.ll +target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" +target triple = "i686-unknown-linux-gnu" + +define dso_local noundef i32 @testFoo(ptr nocapture noundef nonnull readonly align 4 dereferenceable(4) %0) local_unnamed_addr { + %2 = load i32, ptr %0, align 4 + %3 = tail call i32 @getFooValue(i32 noundef %2) +; CHECK: %3 = tail call i32 @getFooValue(i32 noundef %2) + ret i32 %3 +} + +declare i32 @getFooValue(i32 noundef) local_unnamed_addr + +;--- t2.ll +target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" +target triple = "i686-unknown-linux-gnu" + +%0 = type { i32 } + +define i32 @getFooValue(ptr noalias nocapture noundef readonly byval(%0) dereferenceable(4) %0) unnamed_addr { + %2 = load i32, ptr %0, align 4 + ret i32 %2 +}