diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -213,6 +213,27 @@ LLVM_DEBUG(dbgs() << "ARG PROMOTION: Promoting to:" << *NF << "\n" << "From: " << *F); + uint64_t LargestVectorWidth = 0; + for (auto *I : Params) + if (auto *VT = dyn_cast(I)) + LargestVectorWidth = std::max( + LargestVectorWidth, VT->getPrimitiveSizeInBits().getKnownMinSize()); + + auto UpdateMLVW = [LargestVectorWidth, F](AttributeList &PAL) { + Attribute MLVW = PAL.getFnAttr("min-legal-vector-width"); + if (MLVW.isValid()) { + uint64_t OldWidth; + MLVW.getValueAsString().getAsInteger(0, OldWidth); + if (LargestVectorWidth > OldWidth) { + PAL = PAL.addFnAttribute(F->getContext(), "min-legal-vector-width", + llvm::utostr(LargestVectorWidth)); + return true; + } + } + return false; + }; + UpdateMLVW(PAL); + // Recompute the parameter attributes list based on the new arguments for // the function. NF->setAttributes(AttributeList::get(F->getContext(), PAL.getFnAttrs(), @@ -308,6 +329,10 @@ Args.clear(); ArgAttrVec.clear(); + AttributeList PAL = CB.getCaller()->getAttributes(); + if (UpdateMLVW(PAL)) + CB.getCaller()->setAttributes(PAL); + // Update the callgraph to know that the callsite has been transformed. if (ReplaceCallSite) (*ReplaceCallSite)(CB, *NewCS); diff --git a/llvm/test/Transforms/ArgumentPromotion/byval-3.ll b/llvm/test/Transforms/ArgumentPromotion/byval-3.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/ArgumentPromotion/byval-3.ll @@ -0,0 +1,25 @@ +; RUN: opt < %s -passes=argpromotion -S | FileCheck %s + +; CHECK-LABEL: define i32 @foo() #0 { +; CHECK-NEXT: %.val = load <32 x half>, <32 x half>* undef, align 4 +; CHECK-NEXT: call void @bar(<32 x half> %.val) +; CHECK-NEXT: ret i32 0 +; CHECK-NEXT: } + +; CHECK-LABEL: define internal void @bar(<32 x half> %.0.val) #0 { +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; CHECK: attributes #0 = { uwtable "min-legal-vector-width"="512" } + +define i32 @foo() #0 { + call void @bar(<32 x half>* undef) + ret i32 0 +} + +define internal void @bar(<32 x half>*) #0 { + %2 = load <32 x half>, <32 x half>* %0, align 4 + ret void +} + +attributes #0 = { uwtable "min-legal-vector-width"="0" }