Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
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
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2771,7 +2771,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (Arg->getType().isRestrictQualified() ||
(CurCodeDecl &&
CurCodeDecl->hasAttr<SYCLIntelKernelArgsRestrictAttr>() &&
Arg->getType()->isPointerType()))
Arg->getType()->isPointerType()) ||
(Arg->hasAttr<RestrictAttr>() && Arg->getType()->isPointerType()))
AI->addAttr(llvm::Attribute::NoAlias);
}

Expand Down
24 changes: 24 additions & 0 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ class Util {
/// accessor_property_list class.
static bool isAccessorPropertyListType(const QualType &Ty);

/// Checks whether given clang type is a full specialization of the SYCL
/// no_alias class.
static bool isSyclAccessorNoAliasPropertyType(QualType Ty);

/// Checks whether given clang type is a full specialization of the SYCL
/// buffer_location class.
static bool isSyclBufferLocationType(const QualType &Ty);
Expand Down Expand Up @@ -1742,11 +1746,19 @@ class SyclKernelDeclCreator : public SyclKernelFieldHandler {
for (TemplateArgument::pack_iterator Prop = TemplArg.pack_begin();
Prop != TemplArg.pack_end(); ++Prop) {
QualType PropTy = Prop->getAsType();
if (Util::isSyclAccessorNoAliasPropertyType(PropTy))
handleNoAliasProperty(Param, PropTy, Loc);
if (Util::isSyclBufferLocationType(PropTy))
handleBufferLocationProperty(Param, PropTy, Loc);
}
}

void handleNoAliasProperty(ParmVarDecl *Param, QualType PropTy,
SourceLocation Loc) {
ASTContext &Ctx = SemaRef.getASTContext();
Param->addAttr(RestrictAttr::CreateImplicit(Ctx, Loc));
}

// Obtain an integer value stored in a template parameter of buffer_location
// property to pass it to buffer_location kernel attribute
void handleBufferLocationProperty(ParmVarDecl *Param, QualType PropTy,
Expand Down Expand Up @@ -4313,6 +4325,18 @@ bool Util::isSyclKernelHandlerType(const QualType &Ty) {
return matchQualifiedTypeName(Ty, Scopes);
}

bool Util::isSyclAccessorNoAliasPropertyType(QualType Ty) {
std::array<DeclContextDesc, 6> Scopes = {
Util::DeclContextDesc{Decl::Kind::Namespace, "cl"},
Util::DeclContextDesc{Decl::Kind::Namespace, "sycl"},
Util::DeclContextDesc{Decl::Kind::Namespace, "ONEAPI"},
Util::DeclContextDesc{Decl::Kind::Namespace, "property"},
Util::DeclContextDesc{Decl::Kind::CXXRecord, "no_alias"},
Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization,
"instance"}};
return matchQualifiedTypeName(Ty, Scopes);
}

bool Util::isSyclBufferLocationType(const QualType &Ty) {
const StringRef &PropertyName = "buffer_location";
const StringRef &InstanceName = "instance";
Expand Down
9 changes: 9 additions & 0 deletions clang/test/CodeGenSYCL/Inputs/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ struct buffer_location {
} // namespace property
} // namespace INTEL

namespace ONEAPI {
namespace property {
// Compile time known accessor property
struct no_alias {
template <bool> class instance {};
};
} // namespace property
} // namespace ONEAPI

namespace ONEAPI {
template <typename... properties>
class accessor_property_list {};
Expand Down
19 changes: 19 additions & 0 deletions clang/test/CodeGenSYCL/accessor_no_alias_property.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -emit-llvm %s -o - | FileCheck %s

// CHECK: define {{.*}}spir_kernel void @_ZTSZ4mainE15kernel_function({{.*}} noalias {{.*}} %_arg_, {{.*}})

#include "Inputs/sycl.hpp"

int main() {
cl::sycl::accessor<int, 1, cl::sycl::access::mode::read_write,
cl::sycl::access::target::global_buffer,
cl::sycl::access::placeholder::false_t,
cl::sycl::ONEAPI::accessor_property_list<
cl::sycl::ONEAPI::property::no_alias::instance<true>>>
accessorA;
cl::sycl::kernel_single_task<class kernel_function>(
[=]() {
accessorA.use();
});
return 0;
}