From 37d5b6dd66d3fce24f14971414665a1af6d4593b Mon Sep 17 00:00:00 2001 From: amochalo Date: Mon, 13 Jul 2020 12:30:22 +0300 Subject: [PATCH] [SPIRV]Fix translation of user functions into SPIR-V instructions User may get their function a name the same as SPIR-V instruction. In that case thier function call will be translated to SPIR-V instruction call. The only functions that should be translated to SPIR-V instructions are SPIR-V built-ins and they should have __spirv prefix. Add checking for __spirv prefix in demangler to filter SPIR-V built-ins from other function calls. --- llvm-spirv/lib/SPIRV/SPIRVUtil.cpp | 27 ++++---- llvm-spirv/test/transcoding/BitReversePref.ll | 64 +++++++++++++++++++ 2 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 llvm-spirv/test/transcoding/BitReversePref.ll diff --git a/llvm-spirv/lib/SPIRV/SPIRVUtil.cpp b/llvm-spirv/lib/SPIRV/SPIRVUtil.cpp index c20b101186fd0..d816eb2d89759 100644 --- a/llvm-spirv/lib/SPIRV/SPIRVUtil.cpp +++ b/llvm-spirv/lib/SPIRV/SPIRVUtil.cpp @@ -438,6 +438,16 @@ std::string getPostfixForReturnType(const Type *PRetTy, bool IsSigned) { mapLLVMTypeToOCLType(PRetTy, IsSigned); } +// Enqueue kernel, kernel query, pipe and address space cast built-ins +// are not mangled. +bool isNonMangledOCLBuiltin(StringRef Name) { + if (!Name.startswith("__")) + return false; + + return isEnqueueKernelBI(Name) || isKernelQueryBI(Name) || + isPipeOrAddressSpaceCastBI(Name.drop_front(2)); +} + Op getSPIRVFuncOC(StringRef S, SmallVectorImpl *Dec) { Op OC; SmallVector Postfix; @@ -445,9 +455,10 @@ Op getSPIRVFuncOC(StringRef S, SmallVectorImpl *Dec) { if (!oclIsBuiltin(S, Name)) Name = S; StringRef R(Name); - R = dePrefixSPIRVName(R, Postfix); - if (!getByName(R.str(), OC)) + if ((!Name.startswith(kSPIRVName::Prefix) && !isNonMangledOCLBuiltin(S)) || + !getByName(dePrefixSPIRVName(R, Postfix).str(), OC)) { return OpNop; + } if (Dec) for (auto &I : Postfix) Dec->push_back(I.str()); @@ -462,16 +473,6 @@ bool getSPIRVBuiltin(const std::string &OrigName, spv::BuiltIn &B) { return getByName(R.str(), B); } -// Enqueue kernel, kernel query, pipe and address space cast built-ins -// are not mangled. -bool isNonMangledOCLBuiltin(StringRef Name) { - if (!Name.startswith("__")) - return false; - - return isEnqueueKernelBI(Name) || isKernelQueryBI(Name) || - isPipeOrAddressSpaceCastBI(Name.drop_front(2)); -} - // Demangled name is a substring of the name. The DemangledName is updated only // if true is returned bool oclIsBuiltin(StringRef Name, StringRef &DemangledName, bool IsCpp) { @@ -910,7 +911,7 @@ ConstantInt *mapSInt(Module *M, ConstantInt *I, std::function F) { bool isDecoratedSPIRVFunc(const Function *F, StringRef &UndecoratedName) { if (!F->hasName() || !F->getName().startswith(kSPIRVName::Prefix)) return false; - UndecoratedName = undecorateSPIRVFunction(F->getName()); + UndecoratedName = F->getName(); return true; } diff --git a/llvm-spirv/test/transcoding/BitReversePref.ll b/llvm-spirv/test/transcoding/BitReversePref.ll new file mode 100644 index 0000000000000..6c8a98d212038 --- /dev/null +++ b/llvm-spirv/test/transcoding/BitReversePref.ll @@ -0,0 +1,64 @@ +; RUN: llvm-as < %s -o %t.bc +; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s + +;CHECK: Decorate [[#FUNC_NAME:]] LinkageAttributes "_Z10BitReversei" +;CHECK-NOT: BitReverse +;CHECK: FunctionCall [[#]] [[#]] [[#FUNC_NAME]] + +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-linux-sycldevice" + +%"class._ZTSZ4mainE3$_0.anon" = type { i8 } + +$_Z10BitReversei = comdat any + +; Function Attrs: norecurse +define dso_local spir_kernel void @_ZTSZ4mainE15kernel_function() #0 !kernel_arg_addr_space !4 !kernel_arg_access_qual !4 !kernel_arg_type !4 !kernel_arg_base_type !4 !kernel_arg_type_qual !4 { +entry: + %call = call spir_func i32 @_Z10BitReversei(i32 1) + ret void +} + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: inlinehint norecurse nounwind +define linkonce_odr dso_local spir_func i32 @_Z10BitReversei(i32 %value) #3 comdat { +entry: + %value.addr = alloca i32, align 4 + %reversed = alloca i32, align 4 + store i32 %value, i32* %value.addr, align 4, !tbaa !9 + %0 = bitcast i32* %reversed to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #4 + store i32 0, i32* %reversed, align 4, !tbaa !9 + %1 = load i32, i32* %reversed, align 4, !tbaa !9 + %2 = bitcast i32* %reversed to i8* + call void @llvm.lifetime.end.p0i8(i64 4, i8* %2) #4 + ret i32 %1 +} + +attributes #0 = { norecurse "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "sycl-module-id"="Test.cpp" "uniform-work-group-size"="true" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { inlinehint norecurse "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { inlinehint norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #4 = { nounwind } + +!llvm.module.flags = !{!0} +!opencl.spir.version = !{!1} +!spirv.Source = !{!2} +!llvm.ident = !{!3} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 1, i32 2} +!2 = !{i32 4, i32 100000} +!3 = !{!"clang version 11.0.0 (https://github.com/c199914007/llvm.git dc6656ef210464a1c4721eb793b6b6f78a9a2048)"} +!4 = !{} +!5 = !{!6, !6, i64 0} +!6 = !{!"any pointer", !7, i64 0} +!7 = !{!"omnipotent char", !8, i64 0} +!8 = !{!"Simple C++ TBAA"} +!9 = !{!10, !10, i64 0} +!10 = !{!"int", !7, i64 0}