From da85c67302e72e8b6fd42781d0e8bbb02c88c699 Mon Sep 17 00:00:00 2001 From: Wenju He Date: Wed, 8 Nov 2023 08:22:06 +0800 Subject: [PATCH 1/4] [SPV-IR to OCL] Fix mutated builtin call attribute copying When SPIRVToOCL20Pass translates following SPV IR ``` %call = tail call spir_func noundef ptr @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePvi(ptr addrspace(4) noundef %Ptr, i32 noundef 0) declare spir_func ptr @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePvi(ptr addrspace(4), i32) ``` to OCL IR: ``` %call = tail call spir_func noundef ptr @__to_private(ptr addrspace(4) noundef %Ptr) declare spir_func ptr @__to_private(ptr addrspace(4)) ``` , there is error `Attribute after last parameter` at copying attribute to the new call because the old call has an additional AttributeSet for the last argument. The last argument is eliminated. Set tail call for new call if old call is tail call. Revert cafd7e0. Test isn't added since I can only reproduce using SPIRVToOCL20Pass. --- lib/SPIRV/SPIRVBuiltinHelper.cpp | 41 +++++++++++++++----------------- lib/SPIRV/SPIRVBuiltinHelper.h | 4 +++- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/SPIRV/SPIRVBuiltinHelper.cpp b/lib/SPIRV/SPIRVBuiltinHelper.cpp index a648cbac6d..a184f409e1 100644 --- a/lib/SPIRV/SPIRVBuiltinHelper.cpp +++ b/lib/SPIRV/SPIRVBuiltinHelper.cpp @@ -62,8 +62,9 @@ BuiltinCallMutator::BuiltinCallMutator( CallInst *CI, std::string FuncName, ManglingRules Rules, std::function NameMapFn) : CI(CI), FuncName(FuncName), - Attrs(CI->getCalledFunction()->getAttributes()), ReturnTy(CI->getType()), - Args(CI->args()), Rules(Rules), Builder(CI) { + Attrs(CI->getCalledFunction()->getAttributes()), + CallAttrs(CI->getAttributes()), ReturnTy(CI->getType()), Args(CI->args()), + Rules(Rules), Builder(CI) { bool DidDemangle = getParameterTypes(CI->getCalledFunction(), PointerTypes, std::move(NameMapFn)); if (!DidDemangle) { @@ -78,8 +79,8 @@ BuiltinCallMutator::BuiltinCallMutator( BuiltinCallMutator::BuiltinCallMutator(BuiltinCallMutator &&Other) : CI(Other.CI), FuncName(std::move(Other.FuncName)), MutateRet(std::move(Other.MutateRet)), Attrs(Other.Attrs), - ReturnTy(Other.ReturnTy), Args(std::move(Other.Args)), - PointerTypes(std::move(Other.PointerTypes)), + CallAttrs(Other.CallAttrs), ReturnTy(Other.ReturnTy), + Args(std::move(Other.Args)), PointerTypes(std::move(Other.PointerTypes)), Rules(std::move(Other.Rules)), Builder(CI) { // Clear the other's CI instance so that it knows not to construct the actual // call. @@ -103,7 +104,8 @@ Value *BuiltinCallMutator::doConversion() { Builder.Insert(addCallInst(CI->getModule(), FuncName, ReturnTy, Args, &Attrs, nullptr, Mangler.get())); NewCall->copyMetadata(*CI); - NewCall->setAttributes(CI->getAttributes()); + NewCall->setAttributes(CallAttrs); + NewCall->setTailCall(CI->isTailCall()); Value *Result = MutateRet ? MutateRet(Builder, NewCall) : NewCall; Result->takeName(CI); if (!CI->getType()->isVoidTy()) @@ -118,6 +120,8 @@ BuiltinCallMutator &BuiltinCallMutator::setArgs(ArrayRef NewArgs) { // Retain only the function attributes, not any parameter attributes. Attrs = AttributeList::get(CI->getContext(), Attrs.getFnAttrs(), Attrs.getRetAttrs(), {}); + CallAttrs = AttributeList::get(CI->getContext(), CallAttrs.getFnAttrs(), + CallAttrs.getRetAttrs(), {}); Args.clear(); PointerTypes.clear(); for (Value *Arg : NewArgs) { @@ -171,6 +175,8 @@ BuiltinCallMutator &BuiltinCallMutator::insertArg(unsigned Index, PointerTypes.insert(PointerTypes.begin() + Index, Arg.second); moveAttributes(CI->getContext(), Attrs, Index, Args.size() - Index, Index + 1); + moveAttributes(CI->getContext(), CallAttrs, Index, Args.size() - Index, + Index + 1); return *this; } @@ -179,30 +185,21 @@ BuiltinCallMutator &BuiltinCallMutator::replaceArg(unsigned Index, Args[Index] = Arg.first; PointerTypes[Index] = Arg.second; Attrs = Attrs.removeParamAttributes(CI->getContext(), Index); + CallAttrs = CallAttrs.removeParamAttributes(CI->getContext(), Index); return *this; } BuiltinCallMutator &BuiltinCallMutator::removeArg(unsigned Index) { // If the argument being dropped is the last one, there is nothing to move, so // just remove the attributes. + auto &Ctx = CI->getContext(); if (Index == Args.size() - 1) { - // TODO: Remove this workaround when LLVM fixes - // https://github.com/llvm/llvm-project/issues/59746 on - // AttributeList::removeParamAttributes function. - // AttributeList::removeParamAttributes function sets attribute at - // specified index empty so that return value of - // AttributeList::getNumAttrSet() keeps unchanged after that call. When call - // BuiltinCallMutator::removeArg function, there is assert failure on - // BuiltinCallMutator::doConversion() since new CallInst removed arg but - // still holds attribute of that removed arg. - SmallVector ArgAttrs; - for (unsigned I = 0; I < Index; ++I) - ArgAttrs.push_back(Attrs.getParamAttrs(I)); - Attrs = AttributeList::get(CI->getContext(), Attrs.getFnAttrs(), - Attrs.getRetAttrs(), ArgAttrs); - } else - moveAttributes(CI->getContext(), Attrs, Index + 1, Args.size() - Index - 1, - Index); + Attrs = Attrs.removeParamAttributes(Ctx, Index); + CallAttrs = CallAttrs.removeParamAttributes(Ctx, Index); + } else { + moveAttributes(Ctx, Attrs, Index + 1, Args.size() - Index - 1, Index); + moveAttributes(Ctx, CallAttrs, Index + 1, Args.size() - Index - 1, Index); + } Args.erase(Args.begin() + Index); PointerTypes.erase(PointerTypes.begin() + Index); return *this; diff --git a/lib/SPIRV/SPIRVBuiltinHelper.h b/lib/SPIRV/SPIRVBuiltinHelper.h index da5ae0283a..e4b955e82e 100644 --- a/lib/SPIRV/SPIRVBuiltinHelper.h +++ b/lib/SPIRV/SPIRVBuiltinHelper.h @@ -74,8 +74,10 @@ class BuiltinCallMutator { // the new instruction is created. std::function &, llvm::CallInst *)> MutateRet; typedef decltype(MutateRet) MutateRetFuncTy; - // The attribute list for the new call instruction. + // The attribute list for the new called function. llvm::AttributeList Attrs; + // The attribute list for the new call instruction. + llvm::AttributeList CallAttrs; // The return type for the new call instruction. llvm::Type *ReturnTy; // The arguments for the new call instruction. From a6427740ae3354f1d9a5a8799641923ac7adf621 Mon Sep 17 00:00:00 2001 From: Wenju He Date: Thu, 11 Jan 2024 08:12:05 +0800 Subject: [PATCH 2/4] revert `NewCall->setAttributes(CallAttrs)` change in c60327f8 --- lib/SPIRV/SPIRVBuiltinHelper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/SPIRV/SPIRVBuiltinHelper.cpp b/lib/SPIRV/SPIRVBuiltinHelper.cpp index 5efe5752aa..f092d110c1 100644 --- a/lib/SPIRV/SPIRVBuiltinHelper.cpp +++ b/lib/SPIRV/SPIRVBuiltinHelper.cpp @@ -104,6 +104,7 @@ Value *BuiltinCallMutator::doConversion() { Builder.Insert(addCallInst(CI->getModule(), FuncName, ReturnTy, Args, &Attrs, nullptr, Mangler.get())); NewCall->copyMetadata(*CI); + NewCall->setAttributes(CallAttrs); NewCall->setTailCall(CI->isTailCall()); if (CI->hasFnAttr("fpbuiltin-max-error")) { auto Attr = CI->getFnAttr("fpbuiltin-max-error"); From 69e9d026f42fbd6f48ff4d99d31c4746928fc647 Mon Sep 17 00:00:00 2001 From: Wenju He Date: Thu, 11 Jan 2024 08:16:44 +0800 Subject: [PATCH 3/4] add lit --- test/transcoding/call-attribute.ll | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/transcoding/call-attribute.ll diff --git a/test/transcoding/call-attribute.ll b/test/transcoding/call-attribute.ll new file mode 100644 index 0000000000..4c070ca3d7 --- /dev/null +++ b/test/transcoding/call-attribute.ll @@ -0,0 +1,17 @@ +; REQUIRES: pass-plugin +; UNSUPPORTED: target={{.*windows.*}} + +; RUN: opt %load_spirv_lib -passes=spirv-to-ocl20 %s -S -o - | FileCheck %s + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64-unknown-unknown" + +define spir_func ptr @_Z41__SYCL_GenericCastToPtrExplicit_ToPrivateIN4sycl3_V16marrayIdLm17EEEEPU3AS0T_Pv(ptr addrspace(4) %ptr) { +entry: +; CHECK: tail call spir_func noundef ptr @__to_private(ptr addrspace(4) noundef %ptr) + + %call = tail call spir_func noundef ptr @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePvi(ptr addrspace(4) noundef %ptr, i32 noundef 0) + ret ptr null +} + +declare spir_func ptr @_Z42__spirv_GenericCastToPtrExplicit_ToPrivatePvi(ptr addrspace(4), i32) From 27d0b6873b89ef3b68af692d516b66f7c80bcc22 Mon Sep 17 00:00:00 2001 From: Wenju He Date: Wed, 31 Jan 2024 12:12:06 +0800 Subject: [PATCH 4/4] move test to top level --- test/{transcoding => }/call-attribute.ll | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{transcoding => }/call-attribute.ll (100%) diff --git a/test/transcoding/call-attribute.ll b/test/call-attribute.ll similarity index 100% rename from test/transcoding/call-attribute.ll rename to test/call-attribute.ll