Skip to content

Commit 37d5b6d

Browse files
committed
[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.
1 parent 13a1e49 commit 37d5b6d

File tree

2 files changed

+78
-13
lines changed

2 files changed

+78
-13
lines changed

llvm-spirv/lib/SPIRV/SPIRVUtil.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -438,16 +438,27 @@ std::string getPostfixForReturnType(const Type *PRetTy, bool IsSigned) {
438438
mapLLVMTypeToOCLType(PRetTy, IsSigned);
439439
}
440440

441+
// Enqueue kernel, kernel query, pipe and address space cast built-ins
442+
// are not mangled.
443+
bool isNonMangledOCLBuiltin(StringRef Name) {
444+
if (!Name.startswith("__"))
445+
return false;
446+
447+
return isEnqueueKernelBI(Name) || isKernelQueryBI(Name) ||
448+
isPipeOrAddressSpaceCastBI(Name.drop_front(2));
449+
}
450+
441451
Op getSPIRVFuncOC(StringRef S, SmallVectorImpl<std::string> *Dec) {
442452
Op OC;
443453
SmallVector<StringRef, 2> Postfix;
444454
StringRef Name;
445455
if (!oclIsBuiltin(S, Name))
446456
Name = S;
447457
StringRef R(Name);
448-
R = dePrefixSPIRVName(R, Postfix);
449-
if (!getByName(R.str(), OC))
458+
if ((!Name.startswith(kSPIRVName::Prefix) && !isNonMangledOCLBuiltin(S)) ||
459+
!getByName(dePrefixSPIRVName(R, Postfix).str(), OC)) {
450460
return OpNop;
461+
}
451462
if (Dec)
452463
for (auto &I : Postfix)
453464
Dec->push_back(I.str());
@@ -462,16 +473,6 @@ bool getSPIRVBuiltin(const std::string &OrigName, spv::BuiltIn &B) {
462473
return getByName(R.str(), B);
463474
}
464475

465-
// Enqueue kernel, kernel query, pipe and address space cast built-ins
466-
// are not mangled.
467-
bool isNonMangledOCLBuiltin(StringRef Name) {
468-
if (!Name.startswith("__"))
469-
return false;
470-
471-
return isEnqueueKernelBI(Name) || isKernelQueryBI(Name) ||
472-
isPipeOrAddressSpaceCastBI(Name.drop_front(2));
473-
}
474-
475476
// Demangled name is a substring of the name. The DemangledName is updated only
476477
// if true is returned
477478
bool oclIsBuiltin(StringRef Name, StringRef &DemangledName, bool IsCpp) {
@@ -910,7 +911,7 @@ ConstantInt *mapSInt(Module *M, ConstantInt *I, std::function<int(int)> F) {
910911
bool isDecoratedSPIRVFunc(const Function *F, StringRef &UndecoratedName) {
911912
if (!F->hasName() || !F->getName().startswith(kSPIRVName::Prefix))
912913
return false;
913-
UndecoratedName = undecorateSPIRVFunction(F->getName());
914+
UndecoratedName = F->getName();
914915
return true;
915916
}
916917

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
; RUN: llvm-as < %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s
3+
4+
;CHECK: Decorate [[#FUNC_NAME:]] LinkageAttributes "_Z10BitReversei"
5+
;CHECK-NOT: BitReverse
6+
;CHECK: FunctionCall [[#]] [[#]] [[#FUNC_NAME]]
7+
8+
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"
9+
target triple = "spir64-unknown-linux-sycldevice"
10+
11+
%"class._ZTSZ4mainE3$_0.anon" = type { i8 }
12+
13+
$_Z10BitReversei = comdat any
14+
15+
; Function Attrs: norecurse
16+
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 {
17+
entry:
18+
%call = call spir_func i32 @_Z10BitReversei(i32 1)
19+
ret void
20+
}
21+
22+
; Function Attrs: argmemonly nounwind willreturn
23+
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
24+
25+
; Function Attrs: argmemonly nounwind willreturn
26+
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
27+
28+
; Function Attrs: inlinehint norecurse nounwind
29+
define linkonce_odr dso_local spir_func i32 @_Z10BitReversei(i32 %value) #3 comdat {
30+
entry:
31+
%value.addr = alloca i32, align 4
32+
%reversed = alloca i32, align 4
33+
store i32 %value, i32* %value.addr, align 4, !tbaa !9
34+
%0 = bitcast i32* %reversed to i8*
35+
call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #4
36+
store i32 0, i32* %reversed, align 4, !tbaa !9
37+
%1 = load i32, i32* %reversed, align 4, !tbaa !9
38+
%2 = bitcast i32* %reversed to i8*
39+
call void @llvm.lifetime.end.p0i8(i64 4, i8* %2) #4
40+
ret i32 %1
41+
}
42+
43+
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" }
44+
attributes #1 = { argmemonly nounwind willreturn }
45+
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" }
46+
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" }
47+
attributes #4 = { nounwind }
48+
49+
!llvm.module.flags = !{!0}
50+
!opencl.spir.version = !{!1}
51+
!spirv.Source = !{!2}
52+
!llvm.ident = !{!3}
53+
54+
!0 = !{i32 1, !"wchar_size", i32 4}
55+
!1 = !{i32 1, i32 2}
56+
!2 = !{i32 4, i32 100000}
57+
!3 = !{!"clang version 11.0.0 (https://github.com/c199914007/llvm.git dc6656ef210464a1c4721eb793b6b6f78a9a2048)"}
58+
!4 = !{}
59+
!5 = !{!6, !6, i64 0}
60+
!6 = !{!"any pointer", !7, i64 0}
61+
!7 = !{!"omnipotent char", !8, i64 0}
62+
!8 = !{!"Simple C++ TBAA"}
63+
!9 = !{!10, !10, i64 0}
64+
!10 = !{!"int", !7, i64 0}

0 commit comments

Comments
 (0)