Skip to content

Commit 1e36ca2

Browse files
Naghasangoogle-yfyang
authored andcommitted
[clang][SPIRV] Add builtin for OpGenericCastToPtrExplicit and its SPIR-V friendly binding (llvm#137805)
The patch introduce __builtin_spirv_generic_cast_to_ptr_explicit which is lowered to the llvm.spv.generic.cast.to.ptr.explicit intrinsic. The SPIR-V builtins are now split into 3 differents file: BuiltinsSPIRVCore.td, BuiltinsSPIRVVK.td for Vulkan specific builtins, BuiltinsSPIRVCL.td for OpenCL specific builtins and BuiltinsSPIRVCommon.td for common ones. The patch also introduces a new header defining its SPIR-V friendly equivalent (__spirv_GenericCastToPtrExplicit_ToGlobal, __spirv_GenericCastToPtrExplicit_ToLocal and __spirv_GenericCastToPtrExplicit_ToPrivate). The functions are declared as aliases to the new builtin allowing C-like languages to have a definition to rely on as well as gaining proper front-end diagnostics. The motivation for the header is to provide a stable binding for applications or library (such as SYCL) and allows non SPIR-V targets to provide an implementation (via libclc or similar to how it is done for gpuintrin.h).
1 parent edeecdd commit 1e36ca2

24 files changed

+587
-59
lines changed

clang/include/clang/Basic/BuiltinsSPIRV.td

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//===--- BuiltinsSPIRVBase.td - SPIRV Builtin function database -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "clang/Basic/BuiltinsBase.td"
10+
11+
class SPIRVBuiltin<string prototype, list<Attribute> Attr> : Builtin {
12+
let Spellings = ["__builtin_spirv_"#NAME];
13+
let Prototype = prototype;
14+
let Attributes = !listconcat([NoThrow], Attr);
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//===--- BuiltinsSPIRVCL.td - SPIRV Builtin function database ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "clang/Basic/BuiltinsSPIRVBase.td"
10+
11+
def generic_cast_to_ptr_explicit
12+
: SPIRVBuiltin<"void*(void*, int)", [NoThrow, Const, CustomTypeChecking]>;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//===- BuiltinsSPIRVCommon.td - SPIRV Builtin function database -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "clang/Basic/BuiltinsSPIRVBase.td"
10+
11+
def distance : SPIRVBuiltin<"void(...)", [NoThrow, Const]>;
12+
def length : SPIRVBuiltin<"void(...)", [NoThrow, Const]>;
13+
def smoothstep : SPIRVBuiltin<"void(...)", [NoThrow, Const, CustomTypeChecking]>;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//===--- BuiltinsSPIRVVK.td - SPIRV Builtin function database ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
include "clang/Basic/BuiltinsSPIRVBase.td"
10+
11+
12+
def reflect : SPIRVBuiltin<"void(...)", [NoThrow, Const]>;
13+
def faceforward : SPIRVBuiltin<"void(...)", [NoThrow, Const, CustomTypeChecking]>;

clang/include/clang/Basic/CMakeLists.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,17 @@ clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins
109109
SOURCE BuiltinsRISCV.td
110110
TARGET ClangBuiltinsRISCV)
111111

112-
clang_tablegen(BuiltinsSPIRV.inc -gen-clang-builtins
113-
SOURCE BuiltinsSPIRV.td
114-
TARGET ClangBuiltinsSPIRV)
112+
clang_tablegen(BuiltinsSPIRVCommon.inc -gen-clang-builtins
113+
SOURCE BuiltinsSPIRVCommon.td
114+
TARGET ClangBuiltinsSPIRVCommon)
115+
116+
clang_tablegen(BuiltinsSPIRVVK.inc -gen-clang-builtins
117+
SOURCE BuiltinsSPIRVVK.td
118+
TARGET ClangBuiltinsSPIRVVK)
119+
120+
clang_tablegen(BuiltinsSPIRVCL.inc -gen-clang-builtins
121+
SOURCE BuiltinsSPIRVCL.td
122+
TARGET ClangBuiltinsSPIRVCL)
115123

116124
clang_tablegen(BuiltinsX86.inc -gen-clang-builtins
117125
SOURCE BuiltinsX86.td

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4679,7 +4679,7 @@ def err_attribute_preferred_name_arg_invalid : Error<
46794679
"argument %0 to 'preferred_name' attribute is not a typedef for "
46804680
"a specialization of %1">;
46814681
def err_attribute_builtin_alias : Error<
4682-
"%0 attribute can only be applied to a ARM, HLSL or RISC-V builtin">;
4682+
"%0 attribute can only be applied to a ARM, HLSL, SPIR-V or RISC-V builtin">;
46834683

46844684
// called-once attribute diagnostics.
46854685
def err_called_once_attribute_wrong_type : Error<
@@ -12878,6 +12878,16 @@ def err_bit_int_bad_size : Error<"%select{signed|unsigned}0 _BitInt must "
1287812878
def err_bit_int_max_size : Error<"%select{signed|unsigned}0 _BitInt of bit "
1287912879
"sizes greater than %1 not supported">;
1288012880

12881+
// SPIR-V builtins diagnostics
12882+
def err_spirv_invalid_target : Error<
12883+
"builtin requires %select{spirv|spirv32 or spirv64}0 target">;
12884+
def err_spirv_builtin_generic_cast_invalid_arg : Error<
12885+
"expecting a pointer argument to the generic address space">;
12886+
def err_spirv_enum_not_int : Error<
12887+
"%0{storage class} argument for SPIR-V builtin is not a 32-bits integer">;
12888+
def err_spirv_enum_not_valid : Error<
12889+
"invalid value for %select{storage class}0 argument">;
12890+
1288112891
// errors of expect.with.probability
1288212892
def err_probability_not_constant_float : Error<
1288312893
"probability argument to __builtin_expect_with_probability must be constant "

clang/include/clang/Basic/TargetBuiltins.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,17 @@ namespace clang {
157157
enum {
158158
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
159159
#define GET_BUILTIN_ENUMERATORS
160-
#include "clang/Basic/BuiltinsSPIRV.inc"
160+
#include "clang/Basic/BuiltinsSPIRVCommon.inc"
161+
#undef GET_BUILTIN_ENUMERATORS
162+
FirstVKBuiltin,
163+
LastCoreBuiltin = FirstVKBuiltin - 1,
164+
#define GET_BUILTIN_ENUMERATORS
165+
#include "clang/Basic/BuiltinsSPIRVVK.inc"
166+
#undef GET_BUILTIN_ENUMERATORS
167+
FirstCLBuiltin,
168+
LastVKBuiltin = FirstCLBuiltin - 1,
169+
#define GET_BUILTIN_ENUMERATORS
170+
#include "clang/Basic/BuiltinsSPIRVCL.inc"
161171
#undef GET_BUILTIN_ENUMERATORS
162172
LastTSBuiltin
163173
};

clang/include/clang/Sema/SemaSPIRV.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class SemaSPIRV : public SemaBase {
2121
public:
2222
SemaSPIRV(Sema &S);
2323

24-
bool CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
24+
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
25+
CallExpr *TheCall);
2526
};
2627
} // namespace clang
2728

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10165,6 +10165,11 @@ bool ASTContext::canBuiltinBeRedeclared(const FunctionDecl *FD) const {
1016510165
if (LangOpts.HLSL && FD->getBuiltinID() != Builtin::NotBuiltin &&
1016610166
BuiltinInfo.hasCustomTypechecking(FD->getBuiltinID()))
1016710167
return true;
10168+
// Allow redecl custom type checking builtin for SPIR-V.
10169+
if (getTargetInfo().getTriple().isSPIROrSPIRV() &&
10170+
BuiltinInfo.isTSBuiltin(FD->getBuiltinID()) &&
10171+
BuiltinInfo.hasCustomTypechecking(FD->getBuiltinID()))
10172+
return true;
1016810173
return BuiltinInfo.canBeRedeclared(FD->getBuiltinID());
1016910174
}
1017010175

clang/lib/Basic/Targets/SPIR.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,48 @@ static constexpr int NumBuiltins =
2424
clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin;
2525

2626
#define GET_BUILTIN_STR_TABLE
27-
#include "clang/Basic/BuiltinsSPIRV.inc"
27+
#include "clang/Basic/BuiltinsSPIRVCommon.inc"
2828
#undef GET_BUILTIN_STR_TABLE
2929

3030
static constexpr Builtin::Info BuiltinInfos[] = {
3131
#define GET_BUILTIN_INFOS
32-
#include "clang/Basic/BuiltinsSPIRV.inc"
32+
#include "clang/Basic/BuiltinsSPIRVCommon.inc"
3333
#undef GET_BUILTIN_INFOS
3434
};
35-
static_assert(std::size(BuiltinInfos) == NumBuiltins);
35+
36+
namespace CL {
37+
#define GET_BUILTIN_STR_TABLE
38+
#include "clang/Basic/BuiltinsSPIRVCL.inc"
39+
#undef GET_BUILTIN_STR_TABLE
40+
41+
static constexpr Builtin::Info BuiltinInfos[] = {
42+
#define GET_BUILTIN_INFOS
43+
#include "clang/Basic/BuiltinsSPIRVCL.inc"
44+
#undef GET_BUILTIN_INFOS
45+
};
46+
} // namespace CL
47+
48+
namespace VK {
49+
#define GET_BUILTIN_STR_TABLE
50+
#include "clang/Basic/BuiltinsSPIRVVK.inc"
51+
#undef GET_BUILTIN_STR_TABLE
52+
53+
static constexpr Builtin::Info BuiltinInfos[] = {
54+
#define GET_BUILTIN_INFOS
55+
#include "clang/Basic/BuiltinsSPIRVVK.inc"
56+
#undef GET_BUILTIN_INFOS
57+
};
58+
} // namespace VK
59+
60+
static_assert(std::size(BuiltinInfos) + std::size(CL::BuiltinInfos) +
61+
std::size(VK::BuiltinInfos) ==
62+
NumBuiltins);
3663

3764
llvm::SmallVector<Builtin::InfosShard>
38-
SPIRVTargetInfo::getTargetBuiltins() const {
39-
return {{&BuiltinStrings, BuiltinInfos}};
65+
BaseSPIRVTargetInfo::getTargetBuiltins() const {
66+
return {{&BuiltinStrings, BuiltinInfos},
67+
{&VK::BuiltinStrings, VK::BuiltinInfos},
68+
{&CL::BuiltinStrings, CL::BuiltinInfos}};
4069
}
4170

4271
void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts,

clang/lib/Basic/Targets/SPIR.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
293293
assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
294294
}
295295

296+
llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
297+
296298
bool hasFeature(StringRef Feature) const override {
297299
return Feature == "spirv";
298300
}
@@ -321,8 +323,6 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
321323
"v256:256-v512:512-v1024:1024-n8:16:32:64-G10");
322324
}
323325

324-
llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
325-
326326
void getTargetDefines(const LangOptions &Opts,
327327
MacroBuilder &Builder) const override;
328328
};

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,13 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
122122
case llvm::Triple::riscv32:
123123
case llvm::Triple::riscv64:
124124
return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
125+
case llvm::Triple::spirv32:
126+
case llvm::Triple::spirv64:
127+
if (CGF->getTarget().getTriple().getOS() == llvm::Triple::OSType::AMDHSA)
128+
return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
129+
[[fallthrough]];
125130
case llvm::Triple::spirv:
126131
return CGF->EmitSPIRVBuiltinExpr(BuiltinID, E);
127-
case llvm::Triple::spirv64:
128-
if (CGF->getTarget().getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
129-
return nullptr;
130-
return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
131132
default:
132133
return nullptr;
133134
}

clang/lib/CodeGen/TargetBuiltins/SPIR.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned BuiltinID,
8383
/*ReturnType=*/N->getType(), Intrinsic::spv_faceforward,
8484
ArrayRef<Value *>{N, I, Ng}, /*FMFSource=*/nullptr, "spv.faceforward");
8585
}
86+
case SPIRV::BI__builtin_spirv_generic_cast_to_ptr_explicit: {
87+
Value *Ptr = EmitScalarExpr(E->getArg(0));
88+
assert(E->getArg(0)->getType()->hasPointerRepresentation() &&
89+
E->getArg(1)->getType()->hasIntegerRepresentation() &&
90+
"GenericCastToPtrExplicit takes a pointer and an int");
91+
llvm::Type *Res = getTypes().ConvertType(E->getType());
92+
assert(Res->isPointerTy() &&
93+
"GenericCastToPtrExplicit doesn't return a pointer");
94+
llvm::CallInst *Call = Builder.CreateIntrinsic(
95+
/*ReturnType=*/Res, Intrinsic::spv_generic_cast_to_ptr_explicit,
96+
ArrayRef<Value *>{Ptr}, nullptr, "spv.generic_cast");
97+
Call->addRetAttr(llvm::Attribute::AttrKind::NoUndef);
98+
return Call;
99+
}
86100
}
87101
return nullptr;
88102
}

clang/lib/Headers/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ set(riscv_files
132132
andes_vector.h
133133
)
134134

135+
set(spirv_files
136+
__clang_spirv_builtins.h
137+
)
138+
135139
set(systemz_files
136140
s390intrin.h
137141
vecintrin.h
@@ -319,6 +323,7 @@ set(files
319323
${ppc_files}
320324
${ppc_htm_files}
321325
${riscv_files}
326+
${spirv_files}
322327
${systemz_files}
323328
${ve_files}
324329
${x86_files}
@@ -529,6 +534,7 @@ add_dependencies("clang-resource-headers"
529534
"ppc-resource-headers"
530535
"ppc-htm-resource-headers"
531536
"riscv-resource-headers"
537+
"spirv-resource-headers"
532538
"systemz-resource-headers"
533539
"ve-resource-headers"
534540
"webassembly-resource-headers"
@@ -562,6 +568,7 @@ add_header_target("gpu-resource-headers" "${gpu_files}")
562568

563569
# Other header groupings
564570
add_header_target("hlsl-resource-headers" ${hlsl_files})
571+
add_header_target("spirv-resource-headers" ${spirv_files})
565572
add_header_target("opencl-resource-headers" ${opencl_files})
566573
add_header_target("llvm-libc-resource-headers" ${llvm_libc_wrapper_files})
567574
add_header_target("openmp-resource-headers" ${openmp_wrapper_files})
@@ -767,6 +774,12 @@ install(
767774
${EXCLUDE_HLSL}
768775
COMPONENT hlsl-resource-headers)
769776

777+
install(
778+
FILES ${spirv_files}
779+
DESTINATION ${header_install_dir}
780+
EXCLUDE_FROM_ALL
781+
COMPONENT spirv-resource-headers)
782+
770783
install(
771784
FILES ${opencl_files}
772785
DESTINATION ${header_install_dir}
@@ -836,6 +849,9 @@ if (NOT LLVM_ENABLE_IDE)
836849
add_llvm_install_targets(install-riscv-resource-headers
837850
DEPENDS riscv-resource-headers
838851
COMPONENT riscv-resource-headers)
852+
add_llvm_install_targets(install-spirv-resource-headers
853+
DEPENDS spirv-resource-headers
854+
COMPONENT spirv-resource-headers)
839855
add_llvm_install_targets(install-systemz-resource-headers
840856
DEPENDS systemz-resource-headers
841857
COMPONENT systemz-resource-headers)

0 commit comments

Comments
 (0)