Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/BuiltinsSPIRV.td
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

include "clang/Basic/BuiltinsBase.td"

class SPIRVBuiltin<string prototype, list<Attribute> Attr> : Builtin {
let Spellings = ["__builtin_spirv_"#NAME];
let Prototype = prototype;
let Attributes = !listconcat([NoThrow], Attr);
}

def SPIRVDistance : Builtin {
let Spellings = ["__builtin_spirv_distance"];
let Attributes = [NoThrow, Const];
Expand Down Expand Up @@ -37,3 +43,6 @@ def SPIRVFaceForward : Builtin {
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Prototype = "void(...)";
}

def generic_cast_to_ptr_explicit
: SPIRVBuiltin<"void*(void*, int)", [NoThrow, Const, CustomTypeChecking]>;
10 changes: 9 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -4609,7 +4609,7 @@ def err_attribute_preferred_name_arg_invalid : Error<
"argument %0 to 'preferred_name' attribute is not a typedef for "
"a specialization of %1">;
def err_attribute_builtin_alias : Error<
"%0 attribute can only be applied to a ARM, HLSL or RISC-V builtin">;
"%0 attribute can only be applied to a ARM, HLSL, SPIR-V or RISC-V builtin">;

// called-once attribute diagnostics.
def err_called_once_attribute_wrong_type : Error<
Expand Down Expand Up @@ -12740,6 +12740,14 @@ def err_bit_int_bad_size : Error<"%select{signed|unsigned}0 _BitInt must "
def err_bit_int_max_size : Error<"%select{signed|unsigned}0 _BitInt of bit "
"sizes greater than %1 not supported">;

// SPIR-V builtins diagnostics
def err_spirv_builtin_generic_cast_invalid_arg : Error<
"expecting a pointer argument to the generic address space">;
def err_spirv_enum_not_int : Error<
"%0{storage class} argument for SPIR-V builtin is not a 32-bits integer">;
def err_spirv_enum_not_valid : Error<
"invalid value for %select{storage class}0 argument">;

// errors of expect.with.probability
def err_probability_not_constant_float : Error<
"probability argument to __builtin_expect_with_probability must be constant "
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10054,6 +10054,11 @@ bool ASTContext::canBuiltinBeRedeclared(const FunctionDecl *FD) const {
if (LangOpts.HLSL && FD->getBuiltinID() != Builtin::NotBuiltin &&
BuiltinInfo.hasCustomTypechecking(FD->getBuiltinID()))
return true;
// Allow redecl custom type checking builtin for SPIR-V.
if (getTargetInfo().getTriple().isSPIROrSPIRV() &&
BuiltinInfo.isTSBuiltin(FD->getBuiltinID()) &&
BuiltinInfo.hasCustomTypechecking(FD->getBuiltinID()))
return true;
return BuiltinInfo.canBeRedeclared(FD->getBuiltinID());
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/SPIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static constexpr Builtin::Info BuiltinInfos[] = {
static_assert(std::size(BuiltinInfos) == NumBuiltins);

llvm::SmallVector<Builtin::InfosShard>
SPIRVTargetInfo::getTargetBuiltins() const {
BaseSPIRVTargetInfo::getTargetBuiltins() const {
return {{&BuiltinStrings, BuiltinInfos}};
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
}

llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;

bool hasFeature(StringRef Feature) const override {
return Feature == "spirv";
}
Expand Down Expand Up @@ -321,8 +323,6 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
"v256:256-v512:512-v1024:1024-n8:16:32:64-G10");
}

llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;

void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
case llvm::Triple::riscv64:
return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
case llvm::Triple::spirv:
return CGF->EmitSPIRVBuiltinExpr(BuiltinID, E);
case llvm::Triple::spirv32:
case llvm::Triple::spirv64:
if (CGF->getTarget().getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
return nullptr;
return CGF->EmitSPIRVBuiltinExpr(BuiltinID, E);
return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
default:
return nullptr;
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/CodeGen/TargetBuiltins/SPIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,20 @@ Value *CodeGenFunction::EmitSPIRVBuiltinExpr(unsigned BuiltinID,
/*ReturnType=*/N->getType(), Intrinsic::spv_faceforward,
ArrayRef<Value *>{N, I, Ng}, /*FMFSource=*/nullptr, "spv.faceforward");
}
case SPIRV::BI__builtin_spirv_generic_cast_to_ptr_explicit: {
Value *Ptr = EmitScalarExpr(E->getArg(0));
assert(E->getArg(0)->getType()->hasPointerRepresentation() &&
E->getArg(1)->getType()->hasIntegerRepresentation() &&
"GenericCastToPtrExplicit takes a pointer and an int");
llvm::Type *Res = getTypes().ConvertType(E->getType());
assert(Res->isPointerTy() &&
"GenericCastToPtrExplicit doesn't return a pointer");
llvm::CallInst *Call = Builder.CreateIntrinsic(
/*ReturnType=*/Res, Intrinsic::spv_generic_cast_to_ptr_explicit,
ArrayRef<Value *>{Ptr}, nullptr, "spv.generic_cast");
Call->addRetAttr(llvm::Attribute::AttrKind::NoUndef);
return Call;
}
}
return nullptr;
}
16 changes: 16 additions & 0 deletions clang/lib/Headers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ set(riscv_files
sifive_vector.h
)

set(spirv_files
__clang_spirv_builtins.h
)

set(systemz_files
s390intrin.h
vecintrin.h
Expand Down Expand Up @@ -316,6 +320,7 @@ set(files
${ppc_files}
${ppc_htm_files}
${riscv_files}
${spirv_files}
${systemz_files}
${ve_files}
${x86_files}
Expand Down Expand Up @@ -526,6 +531,7 @@ add_dependencies("clang-resource-headers"
"ppc-resource-headers"
"ppc-htm-resource-headers"
"riscv-resource-headers"
"spirv-resource-headers"
"systemz-resource-headers"
"ve-resource-headers"
"webassembly-resource-headers"
Expand Down Expand Up @@ -559,6 +565,7 @@ add_header_target("gpu-resource-headers" "${gpu_files}")

# Other header groupings
add_header_target("hlsl-resource-headers" ${hlsl_files})
add_header_target("spirv-resource-headers" ${spirv_files})
add_header_target("opencl-resource-headers" ${opencl_files})
add_header_target("llvm-libc-resource-headers" ${llvm_libc_wrapper_files})
add_header_target("openmp-resource-headers" ${openmp_wrapper_files})
Expand Down Expand Up @@ -764,6 +771,12 @@ install(
${EXCLUDE_HLSL}
COMPONENT hlsl-resource-headers)

install(
FILES ${spirv_files}
DESTINATION ${header_install_dir}
EXCLUDE_FROM_ALL
COMPONENT spirv-resource-headers)

install(
FILES ${opencl_files}
DESTINATION ${header_install_dir}
Expand Down Expand Up @@ -833,6 +846,9 @@ if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-riscv-resource-headers
DEPENDS riscv-resource-headers
COMPONENT riscv-resource-headers)
add_llvm_install_targets(install-spirv-resource-headers
DEPENDS spirv-resource-headers
COMPONENT spirv-resource-headers)
add_llvm_install_targets(install-systemz-resource-headers
DEPENDS systemz-resource-headers
COMPONENT systemz-resource-headers)
Expand Down
179 changes: 179 additions & 0 deletions clang/lib/Headers/__clang_spirv_builtins.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*===---- spirv_builtin_vars.h - SPIR-V built-in ---------------------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*===-----------------------------------------------------------------------===
*/

#ifndef __SPIRV_BUILTIN_VARS_H
#define __SPIRV_BUILTIN_VARS_H

#if __cplusplus >= 201103L
#define __SPIRV_NOEXCEPT noexcept
#else
#define __SPIRV_NOEXCEPT
#endif

#define __SPIRV_overloadable __attribute__((overloadable))
#define __SPIRV_convergent __attribute__((convergent))
#define __SPIRV_inline __attribute__((always_inline))

#define __global __attribute__((opencl_global))
#define __local __attribute__((opencl_local))
#define __private __attribute__((opencl_private))
#define __constant __attribute__((opencl_constant))
#ifdef __SYCL_DEVICE_ONLY__
#define __generic
#else
#define __generic __attribute__((opencl_generic))
#endif

// Check if SPIR-V builtins are supported.
// As the translator doesn't use the LLVM intrinsics (which would be emitted if
// we use the SPIR-V builtins) we can't rely on the SPIRV32/SPIRV64 etc macros
// to establish if we can use the builtin alias. We disable builtin altogether
// if we do not intent to use the backend. So instead of use target macros, rely
// on a __has_builtin test.
#if (__has_builtin(__builtin_spirv_generic_cast_to_ptr_explicit))
#define __SPIRV_BUILTIN_ALIAS(builtin) \
__attribute__((clang_builtin_alias(builtin)))
#else
#define __SPIRV_BUILTIN_ALIAS(builtin)
#endif

// OpGenericCastToPtrExplicit

extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__global void *__spirv_GenericCastToPtrExplicit_ToGlobal(__generic void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__global const void *
__spirv_GenericCastToPtrExplicit_ToGlobal(__generic const void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__global volatile void *
__spirv_GenericCastToPtrExplicit_ToGlobal(__generic volatile void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__global const volatile void *
__spirv_GenericCastToPtrExplicit_ToGlobal(__generic const volatile void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__local void *__spirv_GenericCastToPtrExplicit_ToLocal(__generic void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__local const void *
__spirv_GenericCastToPtrExplicit_ToLocal(__generic const void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__local volatile void *
__spirv_GenericCastToPtrExplicit_ToLocal(__generic volatile void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__local const volatile void *
__spirv_GenericCastToPtrExplicit_ToLocal(__generic const volatile void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__private void *
__spirv_GenericCastToPtrExplicit_ToPrivate(__generic void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__private const void *
__spirv_GenericCastToPtrExplicit_ToPrivate(__generic const void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__private volatile void *
__spirv_GenericCastToPtrExplicit_ToPrivate(__generic volatile void *,
int) __SPIRV_NOEXCEPT;
extern __SPIRV_overloadable
__SPIRV_BUILTIN_ALIAS(__builtin_spirv_generic_cast_to_ptr_explicit)
__private const volatile void *
__spirv_GenericCastToPtrExplicit_ToPrivate(__generic const volatile void *,
int) __SPIRV_NOEXCEPT;

// OpGenericCastToPtr

static __SPIRV_overloadable __SPIRV_inline __global void *
__spirv_GenericCastToPtr_ToGlobal(__generic void *p, int) __SPIRV_NOEXCEPT {
return (__global void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __global const void *
__spirv_GenericCastToPtr_ToGlobal(__generic const void *p,
int) __SPIRV_NOEXCEPT {
return (__global const void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __global volatile void *
__spirv_GenericCastToPtr_ToGlobal(__generic volatile void *p,
int) __SPIRV_NOEXCEPT {
return (__global volatile void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __global const volatile void *
__spirv_GenericCastToPtr_ToGlobal(__generic const volatile void *p,
int) __SPIRV_NOEXCEPT {
return (__global const volatile void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __local void *
__spirv_GenericCastToPtr_ToLocal(__generic void *p, int) __SPIRV_NOEXCEPT {
return (__local void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __local const void *
__spirv_GenericCastToPtr_ToLocal(__generic const void *p,
int) __SPIRV_NOEXCEPT {
return (__local const void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __local volatile void *
__spirv_GenericCastToPtr_ToLocal(__generic volatile void *p,
int) __SPIRV_NOEXCEPT {
return (__local volatile void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __local const volatile void *
__spirv_GenericCastToPtr_ToLocal(__generic const volatile void *p,
int) __SPIRV_NOEXCEPT {
return (__local const volatile void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __private void *
__spirv_GenericCastToPtr_ToPrivate(__generic void *p, int) __SPIRV_NOEXCEPT {
return (__private void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __private const void *
__spirv_GenericCastToPtr_ToPrivate(__generic const void *p,
int) __SPIRV_NOEXCEPT {
return (__private const void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __private volatile void *
__spirv_GenericCastToPtr_ToPrivate(__generic volatile void *p,
int) __SPIRV_NOEXCEPT {
return (__private volatile void *)p;
}
static __SPIRV_overloadable __SPIRV_inline __private const volatile void *
__spirv_GenericCastToPtr_ToPrivate(__generic const volatile void *p,
int) __SPIRV_NOEXCEPT {
return (__private const volatile void *)p;
}

#undef __SPIRV_overloadable
#undef __SPIRV_convergent
#undef __SPIRV_inline

#undef __global
#undef __local
#undef __constant
#undef __generic

#undef __SPIRV_BUILTIN_ALIAS
#undef __SPIRV_NOEXCEPT

#endif /* __SPIRV_BUILTIN_VARS_H */
6 changes: 5 additions & 1 deletion clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1983,7 +1983,11 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
case llvm::Triple::mips64el:
return MIPS().CheckMipsBuiltinFunctionCall(TI, BuiltinID, TheCall);
case llvm::Triple::spirv:
return SPIRV().CheckSPIRVBuiltinFunctionCall(BuiltinID, TheCall);
case llvm::Triple::spirv32:
case llvm::Triple::spirv64:
if (TI.getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
return SPIRV().CheckSPIRVBuiltinFunctionCall(BuiltinID, TheCall);
return false;
case llvm::Triple::systemz:
return SystemZ().CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall);
case llvm::Triple::x86:
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "clang/Sema/SemaOpenCL.h"
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaRISCV.h"
#include "clang/Sema/SemaSPIRV.h"
#include "clang/Sema/SemaSYCL.h"
#include "clang/Sema/SemaSwift.h"
#include "clang/Sema/SemaWasm.h"
Expand Down Expand Up @@ -5837,12 +5838,13 @@ static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
bool IsSPIRV = S.Context.getTargetInfo().getTriple().isSPIRV();
bool IsHLSL = S.Context.getLangOpts().HLSL;
if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) ||
(IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) &&
!S.ARM().CdeAliasValid(BuiltinID, AliasName)) ||
(IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) ||
(!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL)) {
(!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL && !IsSPIRV)) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not affecting HLSL in any way here.

S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;
return;
}
Expand Down
Loading