forked from OSchip/llvm-project
[OpenCL] Map default address space to alloca address space
For OpenCL, the private address space qualifier is 0 in AST. Before this change, 0 address space qualifier is always mapped to target address space 0. As now target private address space is specified by alloca address space in data layout, address space qualifier 0 needs to be mapped to alloca addr space specified by the data layout. This change has no impact on targets whose alloca addr space is 0. With contributions from Matt Arsenault, Tony Tye and Wen-Heng (Jack) Chung Differential Revision: https://reviews.llvm.org/D31404 llvm-svn: 299965
This commit is contained in:
parent
e95df719e1
commit
b34ec829be
|
@ -2317,12 +2317,7 @@ public:
|
||||||
return getTargetAddressSpace(Q.getAddressSpace());
|
return getTargetAddressSpace(Q.getAddressSpace());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getTargetAddressSpace(unsigned AS) const {
|
unsigned getTargetAddressSpace(unsigned AS) const;
|
||||||
if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
|
|
||||||
return AS;
|
|
||||||
else
|
|
||||||
return (*AddrSpaceMap)[AS - LangAS::Offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get target-dependent integer value for null pointer which is used for
|
/// Get target-dependent integer value for null pointer which is used for
|
||||||
/// constant folding.
|
/// constant folding.
|
||||||
|
@ -2330,8 +2325,7 @@ public:
|
||||||
|
|
||||||
bool addressSpaceMapManglingFor(unsigned AS) const {
|
bool addressSpaceMapManglingFor(unsigned AS) const {
|
||||||
return AddrSpaceMapMangling ||
|
return AddrSpaceMapMangling ||
|
||||||
AS < LangAS::Offset ||
|
AS >= LangAS::Count;
|
||||||
AS >= LangAS::Offset + LangAS::Count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -333,6 +333,20 @@ public:
|
||||||
|
|
||||||
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
|
bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
|
||||||
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
|
unsigned getAddressSpace() const { return Mask >> AddressSpaceShift; }
|
||||||
|
/// Get the address space attribute value to be printed by diagnostics.
|
||||||
|
unsigned getAddressSpaceAttributePrintValue() const {
|
||||||
|
auto Addr = getAddressSpace();
|
||||||
|
// This function is not supposed to be used with language specific
|
||||||
|
// address spaces. If that happens, the diagnostic message should consider
|
||||||
|
// printing the QualType instead of the address space value.
|
||||||
|
assert(Addr == 0 || Addr >= LangAS::Count);
|
||||||
|
if (Addr)
|
||||||
|
return Addr - LangAS::Count;
|
||||||
|
// TODO: The diagnostic messages where Addr may be 0 should be fixed
|
||||||
|
// since it cannot differentiate the situation where 0 denotes the default
|
||||||
|
// address space or user specified __attribute__((address_space(0))).
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
void setAddressSpace(unsigned space) {
|
void setAddressSpace(unsigned space) {
|
||||||
assert(space <= MaxAddressSpace);
|
assert(space <= MaxAddressSpace);
|
||||||
Mask = (Mask & ~AddressSpaceMask)
|
Mask = (Mask & ~AddressSpaceMask)
|
||||||
|
|
|
@ -20,24 +20,32 @@ namespace clang {
|
||||||
|
|
||||||
namespace LangAS {
|
namespace LangAS {
|
||||||
|
|
||||||
/// \brief Defines the set of possible language-specific address spaces.
|
/// \brief Defines the address space values used by the address space qualifier
|
||||||
|
/// of QualType.
|
||||||
///
|
///
|
||||||
/// This uses a high starting offset so as not to conflict with any address
|
|
||||||
/// space used by a target.
|
|
||||||
enum ID {
|
enum ID {
|
||||||
Offset = 0x7FFF00,
|
// The default value 0 is the value used in QualType for the the situation
|
||||||
|
// where there is no address space qualifier. For most languages, this also
|
||||||
|
// corresponds to the situation where there is no address space qualifier in
|
||||||
|
// the source code, except for OpenCL, where the address space value 0 in
|
||||||
|
// QualType represents private address space in OpenCL source code.
|
||||||
|
Default = 0,
|
||||||
|
|
||||||
opencl_global = Offset,
|
// OpenCL specific address spaces.
|
||||||
|
opencl_global,
|
||||||
opencl_local,
|
opencl_local,
|
||||||
opencl_constant,
|
opencl_constant,
|
||||||
opencl_generic,
|
opencl_generic,
|
||||||
|
|
||||||
|
// CUDA specific address spaces.
|
||||||
cuda_device,
|
cuda_device,
|
||||||
cuda_constant,
|
cuda_constant,
|
||||||
cuda_shared,
|
cuda_shared,
|
||||||
|
|
||||||
Last,
|
// This denotes the count of language-specific address spaces and also
|
||||||
Count = Last-Offset
|
// the offset added to the target-specific address spaces, which are usually
|
||||||
|
// specified by address space attributes __attribute__(address_space(n))).
|
||||||
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The type of a lookup table which maps from language-specific address spaces
|
/// The type of a lookup table which maps from language-specific address spaces
|
||||||
|
|
|
@ -703,6 +703,7 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T,
|
||||||
// The fake address space map must have a distinct entry for each
|
// The fake address space map must have a distinct entry for each
|
||||||
// language-specific address space.
|
// language-specific address space.
|
||||||
static const unsigned FakeAddrSpaceMap[] = {
|
static const unsigned FakeAddrSpaceMap[] = {
|
||||||
|
0, // Default
|
||||||
1, // opencl_global
|
1, // opencl_global
|
||||||
3, // opencl_local
|
3, // opencl_local
|
||||||
2, // opencl_constant
|
2, // opencl_constant
|
||||||
|
@ -8727,7 +8728,8 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
|
||||||
char *End;
|
char *End;
|
||||||
unsigned AddrSpace = strtoul(Str, &End, 10);
|
unsigned AddrSpace = strtoul(Str, &End, 10);
|
||||||
if (End != Str && AddrSpace != 0) {
|
if (End != Str && AddrSpace != 0) {
|
||||||
Type = Context.getAddrSpaceQualType(Type, AddrSpace);
|
Type = Context.getAddrSpaceQualType(Type, AddrSpace +
|
||||||
|
LangAS::Count);
|
||||||
Str = End;
|
Str = End;
|
||||||
}
|
}
|
||||||
if (c == '*')
|
if (c == '*')
|
||||||
|
@ -9546,6 +9548,18 @@ uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const {
|
||||||
return getTargetInfo().getNullPointerValue(AS);
|
return getTargetInfo().getNullPointerValue(AS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned ASTContext::getTargetAddressSpace(unsigned AS) const {
|
||||||
|
// For OpenCL, only function local variables are not explicitly marked with
|
||||||
|
// an address space in the AST, and these need to be the address space of
|
||||||
|
// alloca.
|
||||||
|
if (!AS && LangOpts.OpenCL)
|
||||||
|
return getTargetInfo().getDataLayout().getAllocaAddrSpace();
|
||||||
|
if (AS >= LangAS::Count)
|
||||||
|
return AS - LangAS::Count;
|
||||||
|
else
|
||||||
|
return (*AddrSpaceMap)[AS];
|
||||||
|
}
|
||||||
|
|
||||||
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
|
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
|
||||||
// doesn't include ASTContext.h
|
// doesn't include ASTContext.h
|
||||||
template
|
template
|
||||||
|
|
|
@ -627,7 +627,8 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
|
||||||
// Const stuff is obviously not modifiable.
|
// Const stuff is obviously not modifiable.
|
||||||
if (CT.isConstQualified())
|
if (CT.isConstQualified())
|
||||||
return Cl::CM_ConstQualified;
|
return Cl::CM_ConstQualified;
|
||||||
if (CT.getQualifiers().getAddressSpace() == LangAS::opencl_constant)
|
if (Ctx.getLangOpts().OpenCL &&
|
||||||
|
CT.getQualifiers().getAddressSpace() == LangAS::opencl_constant)
|
||||||
return Cl::CM_ConstAddrSpace;
|
return Cl::CM_ConstAddrSpace;
|
||||||
|
|
||||||
// Arrays are not modifiable, only their elements are.
|
// Arrays are not modifiable, only their elements are.
|
||||||
|
|
|
@ -1653,14 +1653,22 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
|
||||||
OS << "__local";
|
OS << "__local";
|
||||||
break;
|
break;
|
||||||
case LangAS::opencl_constant:
|
case LangAS::opencl_constant:
|
||||||
|
case LangAS::cuda_constant:
|
||||||
OS << "__constant";
|
OS << "__constant";
|
||||||
break;
|
break;
|
||||||
case LangAS::opencl_generic:
|
case LangAS::opencl_generic:
|
||||||
OS << "__generic";
|
OS << "__generic";
|
||||||
break;
|
break;
|
||||||
|
case LangAS::cuda_device:
|
||||||
|
OS << "__device";
|
||||||
|
break;
|
||||||
|
case LangAS::cuda_shared:
|
||||||
|
OS << "__shared";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
assert(addrspace >= LangAS::Count);
|
||||||
OS << "__attribute__((address_space(";
|
OS << "__attribute__((address_space(";
|
||||||
OS << addrspace;
|
OS << addrspace - LangAS::Count;
|
||||||
OS << ")))";
|
OS << ")))";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1777,6 +1777,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned NVPTXAddrSpaceMap[] = {
|
static const unsigned NVPTXAddrSpaceMap[] = {
|
||||||
|
0, // Default
|
||||||
1, // opencl_global
|
1, // opencl_global
|
||||||
3, // opencl_local
|
3, // opencl_local
|
||||||
4, // opencl_constant
|
4, // opencl_constant
|
||||||
|
@ -2031,6 +2032,7 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const LangAS::Map AMDGPUPrivateIsZeroMap = {
|
static const LangAS::Map AMDGPUPrivateIsZeroMap = {
|
||||||
|
4, // Default
|
||||||
1, // opencl_global
|
1, // opencl_global
|
||||||
3, // opencl_local
|
3, // opencl_local
|
||||||
2, // opencl_constant
|
2, // opencl_constant
|
||||||
|
@ -2040,6 +2042,7 @@ static const LangAS::Map AMDGPUPrivateIsZeroMap = {
|
||||||
3 // cuda_shared
|
3 // cuda_shared
|
||||||
};
|
};
|
||||||
static const LangAS::Map AMDGPUGenericIsZeroMap = {
|
static const LangAS::Map AMDGPUGenericIsZeroMap = {
|
||||||
|
0, // Default
|
||||||
1, // opencl_global
|
1, // opencl_global
|
||||||
3, // opencl_local
|
3, // opencl_local
|
||||||
2, // opencl_constant
|
2, // opencl_constant
|
||||||
|
@ -2064,7 +2067,7 @@ static const char *const DataLayoutStringSIPrivateIsZero =
|
||||||
static const char *const DataLayoutStringSIGenericIsZero =
|
static const char *const DataLayoutStringSIGenericIsZero =
|
||||||
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32"
|
"e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32"
|
||||||
"-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
|
"-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
|
||||||
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
|
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5";
|
||||||
|
|
||||||
class AMDGPUTargetInfo final : public TargetInfo {
|
class AMDGPUTargetInfo final : public TargetInfo {
|
||||||
static const Builtin::Info BuiltinInfo[];
|
static const Builtin::Info BuiltinInfo[];
|
||||||
|
@ -2139,6 +2142,7 @@ public:
|
||||||
(IsGenericZero ? DataLayoutStringSIGenericIsZero :
|
(IsGenericZero ? DataLayoutStringSIGenericIsZero :
|
||||||
DataLayoutStringSIPrivateIsZero)
|
DataLayoutStringSIPrivateIsZero)
|
||||||
: DataLayoutStringR600);
|
: DataLayoutStringR600);
|
||||||
|
assert(DataLayout->getAllocaAddrSpace() == AS.Private);
|
||||||
|
|
||||||
AddrSpaceMap = IsGenericZero ? &AMDGPUGenericIsZeroMap :
|
AddrSpaceMap = IsGenericZero ? &AMDGPUGenericIsZeroMap :
|
||||||
&AMDGPUPrivateIsZeroMap;
|
&AMDGPUPrivateIsZeroMap;
|
||||||
|
@ -7408,6 +7412,7 @@ ArrayRef<const char *> MSP430TargetInfo::getGCCRegNames() const {
|
||||||
// publicly available in http://tce.cs.tut.fi
|
// publicly available in http://tce.cs.tut.fi
|
||||||
|
|
||||||
static const unsigned TCEOpenCLAddrSpaceMap[] = {
|
static const unsigned TCEOpenCLAddrSpaceMap[] = {
|
||||||
|
0, // Default
|
||||||
3, // opencl_global
|
3, // opencl_global
|
||||||
4, // opencl_local
|
4, // opencl_local
|
||||||
5, // opencl_constant
|
5, // opencl_constant
|
||||||
|
@ -8374,6 +8379,7 @@ const Builtin::Info Le64TargetInfo::BuiltinInfo[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned SPIRAddrSpaceMap[] = {
|
static const unsigned SPIRAddrSpaceMap[] = {
|
||||||
|
0, // Default
|
||||||
1, // opencl_global
|
1, // opencl_global
|
||||||
3, // opencl_local
|
3, // opencl_local
|
||||||
2, // opencl_constant
|
2, // opencl_constant
|
||||||
|
|
|
@ -2048,9 +2048,10 @@ bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
|
||||||
else if (AllocType->isVariablyModifiedType())
|
else if (AllocType->isVariablyModifiedType())
|
||||||
return Diag(Loc, diag::err_variably_modified_new_type)
|
return Diag(Loc, diag::err_variably_modified_new_type)
|
||||||
<< AllocType;
|
<< AllocType;
|
||||||
else if (unsigned AddressSpace = AllocType.getAddressSpace())
|
else if (AllocType.getAddressSpace())
|
||||||
return Diag(Loc, diag::err_address_space_qualified_new)
|
return Diag(Loc, diag::err_address_space_qualified_new)
|
||||||
<< AllocType.getUnqualifiedType() << AddressSpace;
|
<< AllocType.getUnqualifiedType()
|
||||||
|
<< AllocType.getQualifiers().getAddressSpaceAttributePrintValue();
|
||||||
else if (getLangOpts().ObjCAutoRefCount) {
|
else if (getLangOpts().ObjCAutoRefCount) {
|
||||||
if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
|
if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
|
||||||
QualType BaseAllocType = Context.getBaseElementType(AT);
|
QualType BaseAllocType = Context.getBaseElementType(AT);
|
||||||
|
@ -3117,10 +3118,11 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
||||||
QualType Pointee = Type->getAs<PointerType>()->getPointeeType();
|
QualType Pointee = Type->getAs<PointerType>()->getPointeeType();
|
||||||
QualType PointeeElem = Context.getBaseElementType(Pointee);
|
QualType PointeeElem = Context.getBaseElementType(Pointee);
|
||||||
|
|
||||||
if (unsigned AddressSpace = Pointee.getAddressSpace())
|
if (Pointee.getAddressSpace())
|
||||||
return Diag(Ex.get()->getLocStart(),
|
return Diag(Ex.get()->getLocStart(),
|
||||||
diag::err_address_space_qualified_delete)
|
diag::err_address_space_qualified_delete)
|
||||||
<< Pointee.getUnqualifiedType() << AddressSpace;
|
<< Pointee.getUnqualifiedType()
|
||||||
|
<< Pointee.getQualifiers().getAddressSpaceAttributePrintValue();
|
||||||
|
|
||||||
CXXRecordDecl *PointeeRD = nullptr;
|
CXXRecordDecl *PointeeRD = nullptr;
|
||||||
if (Pointee->isVoidType() && !isSFINAEContext()) {
|
if (Pointee->isVoidType() && !isSFINAEContext()) {
|
||||||
|
|
|
@ -9528,7 +9528,8 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
|
||||||
<< (unsigned) FnKind << FnDesc
|
<< (unsigned) FnKind << FnDesc
|
||||||
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
|
<< (FromExpr ? FromExpr->getSourceRange() : SourceRange())
|
||||||
<< FromTy
|
<< FromTy
|
||||||
<< FromQs.getAddressSpace() << ToQs.getAddressSpace()
|
<< FromQs.getAddressSpaceAttributePrintValue()
|
||||||
|
<< ToQs.getAddressSpaceAttributePrintValue()
|
||||||
<< (unsigned) isObjectArgument << I+1;
|
<< (unsigned) isObjectArgument << I+1;
|
||||||
MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
|
MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -5529,14 +5529,14 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
|
||||||
addrSpace.setIsSigned(false);
|
addrSpace.setIsSigned(false);
|
||||||
}
|
}
|
||||||
llvm::APSInt max(addrSpace.getBitWidth());
|
llvm::APSInt max(addrSpace.getBitWidth());
|
||||||
max = Qualifiers::MaxAddressSpace;
|
max = Qualifiers::MaxAddressSpace - LangAS::Count;
|
||||||
if (addrSpace > max) {
|
if (addrSpace > max) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
|
S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
|
||||||
<< int(Qualifiers::MaxAddressSpace) << ASArgExpr->getSourceRange();
|
<< (unsigned)max.getZExtValue() << ASArgExpr->getSourceRange();
|
||||||
Attr.setInvalid();
|
Attr.setInvalid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ASIdx = static_cast<unsigned>(addrSpace.getZExtValue());
|
ASIdx = static_cast<unsigned>(addrSpace.getZExtValue()) + LangAS::Count;
|
||||||
} else {
|
} else {
|
||||||
// The keyword-based type attributes imply which address space to use.
|
// The keyword-based type attributes imply which address space to use.
|
||||||
switch (Attr.getKind()) {
|
switch (Attr.getKind()) {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck %s
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck -check-prefixes=CHECK,GIZ %s
|
||||||
|
// RUN: %clang_cc1 -triple amdgcn -emit-llvm < %s | FileCheck -check-prefixes=CHECK,PIZ %s
|
||||||
|
// RUN: %clang_cc1 -triple amdgcn---amdgiz -emit-llvm < %s | FileCheck -check-prefixes=CHeCK,GIZ %s
|
||||||
|
|
||||||
// CHECK: @foo = common addrspace(1) global
|
// CHECK: @foo = common addrspace(1) global
|
||||||
int foo __attribute__((address_space(1)));
|
int foo __attribute__((address_space(1)));
|
||||||
|
@ -6,6 +8,9 @@ int foo __attribute__((address_space(1)));
|
||||||
// CHECK: @ban = common addrspace(1) global
|
// CHECK: @ban = common addrspace(1) global
|
||||||
int ban[10] __attribute__((address_space(1)));
|
int ban[10] __attribute__((address_space(1)));
|
||||||
|
|
||||||
|
// CHECK: @a = common global
|
||||||
|
int a __attribute__((address_space(0)));
|
||||||
|
|
||||||
// CHECK-LABEL: define i32 @test1()
|
// CHECK-LABEL: define i32 @test1()
|
||||||
// CHECK: load i32, i32 addrspace(1)* @foo
|
// CHECK: load i32, i32 addrspace(1)* @foo
|
||||||
int test1() { return foo; }
|
int test1() { return foo; }
|
||||||
|
@ -19,9 +24,11 @@ int test2(int i) { return ban[i]; }
|
||||||
__attribute__((address_space(2))) int *A, *B;
|
__attribute__((address_space(2))) int *A, *B;
|
||||||
|
|
||||||
// CHECK-LABEL: define void @test3()
|
// CHECK-LABEL: define void @test3()
|
||||||
// CHECK: load i32 addrspace(2)*, i32 addrspace(2)** @B
|
// GIZ: load i32 addrspace(2)*, i32 addrspace(2)** @B
|
||||||
|
// PIZ: load i32 addrspace(2)*, i32 addrspace(2)* addrspace(4)* @B
|
||||||
// CHECK: load i32, i32 addrspace(2)*
|
// CHECK: load i32, i32 addrspace(2)*
|
||||||
// CHECK: load i32 addrspace(2)*, i32 addrspace(2)** @A
|
// GIZ: load i32 addrspace(2)*, i32 addrspace(2)** @A
|
||||||
|
// PIZ: load i32 addrspace(2)*, i32 addrspace(2)* addrspace(4)* @A
|
||||||
// CHECK: store i32 {{.*}}, i32 addrspace(2)*
|
// CHECK: store i32 {{.*}}, i32 addrspace(2)*
|
||||||
void test3() {
|
void test3() {
|
||||||
*A = *B;
|
*A = *B;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
// RUN: %clang_cc1 -triple amdgcn -emit-llvm < %s | FileCheck -check-prefixes=PIZ,COM %s
|
||||||
|
// RUN: %clang_cc1 -triple amdgcn---amdgiz -emit-llvm < %s | FileCheck -check-prefixes=CHECK,COM %s
|
||||||
|
|
||||||
|
// PIZ-DAG: @foo = common addrspace(4) global i32 0
|
||||||
|
// CHECK-DAG: @foo = common global i32 0
|
||||||
|
int foo;
|
||||||
|
|
||||||
|
// PIZ-DAG: @ban = common addrspace(4) global [10 x i32] zeroinitializer
|
||||||
|
// CHECK-DAG: @ban = common global [10 x i32] zeroinitializer
|
||||||
|
int ban[10];
|
||||||
|
|
||||||
|
// PIZ-DAG: @A = common addrspace(4) global i32 addrspace(4)* null
|
||||||
|
// PIZ-DAG: @B = common addrspace(4) global i32 addrspace(4)* null
|
||||||
|
// CHECK-DAG: @A = common global i32* null
|
||||||
|
// CHECK-DAG: @B = common global i32* null
|
||||||
|
int *A;
|
||||||
|
int *B;
|
||||||
|
|
||||||
|
// COM-LABEL: define i32 @test1()
|
||||||
|
// PIZ: load i32, i32 addrspace(4)* @foo
|
||||||
|
// CHECK: load i32, i32* @foo
|
||||||
|
int test1() { return foo; }
|
||||||
|
|
||||||
|
// COM-LABEL: define i32 @test2(i32 %i)
|
||||||
|
// PIZ: load i32, i32 addrspace(4)*
|
||||||
|
// PIZ-NEXT: ret i32
|
||||||
|
// CHECK: load i32, i32*
|
||||||
|
// CHECK-NEXT: ret i32
|
||||||
|
int test2(int i) { return ban[i]; }
|
||||||
|
|
||||||
|
// COM-LABEL: define void @test3()
|
||||||
|
// PIZ: load i32 addrspace(4)*, i32 addrspace(4)* addrspace(4)* @B
|
||||||
|
// PIZ: load i32, i32 addrspace(4)*
|
||||||
|
// PIZ: load i32 addrspace(4)*, i32 addrspace(4)* addrspace(4)* @A
|
||||||
|
// PIZ: store i32 {{.*}}, i32 addrspace(4)*
|
||||||
|
// CHECK: load i32*, i32** @B
|
||||||
|
// CHECK: load i32, i32*
|
||||||
|
// CHECK: load i32*, i32** @A
|
||||||
|
// CHECK: store i32 {{.*}}, i32*
|
||||||
|
void test3() {
|
||||||
|
*A = *B;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PIZ-LABEL: define void @test4(i32 addrspace(4)* %a)
|
||||||
|
// PIZ: %[[a_addr:.*]] = alloca i32 addrspace(4)*
|
||||||
|
// PIZ: store i32 addrspace(4)* %a, i32 addrspace(4)** %[[a_addr]]
|
||||||
|
// PIZ: %[[r0:.*]] = load i32 addrspace(4)*, i32 addrspace(4)** %[[a_addr]]
|
||||||
|
// PIZ: %[[arrayidx:.*]] = getelementptr inbounds i32, i32 addrspace(4)* %[[r0]]
|
||||||
|
// PIZ: store i32 0, i32 addrspace(4)* %[[arrayidx]]
|
||||||
|
// CHECK-LABEL: define void @test4(i32* %a)
|
||||||
|
// CHECK: %[[a_addr:.*]] = alloca i32*, align 4, addrspace(5)
|
||||||
|
// CHECK: store i32* %a, i32* addrspace(5)* %[[a_addr]]
|
||||||
|
// CHECK: %[[r0:.*]] = load i32*, i32* addrspace(5)* %[[a_addr]]
|
||||||
|
// CHECK: %[[arrayidx:.*]] = getelementptr inbounds i32, i32* %[[r0]]
|
||||||
|
// CHECK: store i32 0, i32* %[[arrayidx]]
|
||||||
|
void test4(int *a) {
|
||||||
|
a[0] = 0;
|
||||||
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
// RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s
|
// RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR
|
||||||
// RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefix=CL20
|
// RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR
|
||||||
|
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-opencl -emit-llvm -o - | FileCheck --check-prefixes=CHECK,SPIR %s
|
||||||
|
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-opencl -DCL20 -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20SPIR
|
||||||
|
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-amdgizcl -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,GIZ
|
||||||
|
// RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa-amdgizcl -DCL20 -cl-std=CL2.0 -emit-llvm -o - | FileCheck %s --check-prefixes=CL20,CL20GIZ
|
||||||
|
|
||||||
// CHECK: i32* %arg
|
// SPIR: i32* %arg
|
||||||
|
// GIZ: i32 addrspace(5)* %arg
|
||||||
void f__p(__private int *arg) {}
|
void f__p(__private int *arg) {}
|
||||||
|
|
||||||
// CHECK: i32 addrspace(1)* %arg
|
// CHECK: i32 addrspace(1)* %arg
|
||||||
|
@ -13,7 +18,8 @@ void f__l(__local int *arg) {}
|
||||||
// CHECK: i32 addrspace(2)* %arg
|
// CHECK: i32 addrspace(2)* %arg
|
||||||
void f__c(__constant int *arg) {}
|
void f__c(__constant int *arg) {}
|
||||||
|
|
||||||
// CHECK: i32* %arg
|
// SPIR: i32* %arg
|
||||||
|
// GIZ: i32 addrspace(5)* %arg
|
||||||
void fp(private int *arg) {}
|
void fp(private int *arg) {}
|
||||||
|
|
||||||
// CHECK: i32 addrspace(1)* %arg
|
// CHECK: i32 addrspace(1)* %arg
|
||||||
|
@ -29,16 +35,21 @@ void fc(constant int *arg) {}
|
||||||
int i;
|
int i;
|
||||||
// CL20-DAG: @i = common addrspace(1) global i32 0
|
// CL20-DAG: @i = common addrspace(1) global i32 0
|
||||||
int *ptr;
|
int *ptr;
|
||||||
// CL20-DAG: @ptr = common addrspace(1) global i32 addrspace(4)* null
|
// CL20SPIR-DAG: @ptr = common addrspace(1) global i32 addrspace(4)* null
|
||||||
|
// CL20GIZ-DAG: @ptr = common addrspace(1) global i32* null
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// CHECK: i32* %arg
|
// SPIR: i32* %arg
|
||||||
// CL20-DAG: i32 addrspace(4)* %arg
|
// GIZ: i32 addrspace(5)* %arg
|
||||||
|
// CL20SPIR-DAG: i32 addrspace(4)* %arg
|
||||||
|
// CL20GIZ-DAG: i32* %arg
|
||||||
void f(int *arg) {
|
void f(int *arg) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
// CHECK: %i = alloca i32,
|
// SPIR: %i = alloca i32,
|
||||||
// CL20-DAG: %i = alloca i32,
|
// GIZ: %i = alloca i32{{.*}}addrspace(5)
|
||||||
|
// CL20SPIR-DAG: %i = alloca i32,
|
||||||
|
// CL20GIZ-DAG: %i = alloca i32{{.*}}addrspace(5)
|
||||||
|
|
||||||
#ifdef CL20
|
#ifdef CL20
|
||||||
static int ii;
|
static int ii;
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
// RUN: %clang_cc1 %s -O0 -triple amdgcn---amdgizcl -emit-llvm -o - | FileCheck -check-prefix=GIZ %s
|
// RUN: %clang_cc1 %s -O0 -triple amdgcn---amdgizcl -emit-llvm -o - | FileCheck -check-prefix=GIZ %s
|
||||||
|
|
||||||
// CHECK: target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
|
// CHECK: target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
|
||||||
// GIZ: target datalayout = "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
|
// GIZ: target datalayout = "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"
|
||||||
void foo(void) {}
|
void foo(void) {}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck %s
|
// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s
|
||||||
|
// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-opencl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s
|
||||||
|
// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-amdgizcl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,GIZ %s
|
||||||
|
|
||||||
constant int sz0 = 5;
|
constant int sz0 = 5;
|
||||||
// CHECK: @sz0 = addrspace(2) constant i32 5
|
// CHECK: @sz0 = addrspace(2) constant i32 5
|
||||||
|
@ -11,8 +13,12 @@ const constant int sz2 = 8;
|
||||||
kernel void testvla()
|
kernel void testvla()
|
||||||
{
|
{
|
||||||
int vla0[sz0];
|
int vla0[sz0];
|
||||||
// CHECK: %vla0 = alloca [5 x i32]
|
// SPIR: %vla0 = alloca [5 x i32]
|
||||||
|
// SPIR-NOT: %vla0 = alloca [5 x i32]{{.*}}addrspace
|
||||||
|
// GIZ: %vla0 = alloca [5 x i32]{{.*}}addrspace(5)
|
||||||
char vla1[sz1];
|
char vla1[sz1];
|
||||||
// CHECK: %vla1 = alloca [16 x i8]
|
// SPIR: %vla1 = alloca [16 x i8]
|
||||||
|
// SPIR-NOT: %vla1 = alloca [16 x i8]{{.*}}addrspace
|
||||||
|
// GIZ: %vla1 = alloca [16 x i8]{{.*}}addrspace(5)
|
||||||
local short vla2[sz2];
|
local short vla2[sz2];
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ void foo(_AS3 float *a,
|
||||||
_AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}}
|
_AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}}
|
||||||
|
|
||||||
__attribute__((address_space(-1))) int *_boundsA; // expected-error {{address space is negative}}
|
__attribute__((address_space(-1))) int *_boundsA; // expected-error {{address space is negative}}
|
||||||
__attribute__((address_space(0x7FFFFF))) int *_boundsB;
|
__attribute__((address_space(0x7FFFFF))) int *_boundsB; // expected-error {{address space is larger than the maximum supported}}
|
||||||
__attribute__((address_space(0x1000000))) int *_boundsC; // expected-error {{address space is larger than the maximum supported}}
|
__attribute__((address_space(0x1000000))) int *_boundsC; // expected-error {{address space is larger than the maximum supported}}
|
||||||
// chosen specifically to overflow 32 bits and come out reasonable
|
// chosen specifically to overflow 32 bits and come out reasonable
|
||||||
__attribute__((address_space(4294967500))) int *_boundsD; // expected-error {{address space is larger than the maximum supported}}
|
__attribute__((address_space(4294967500))) int *_boundsD; // expected-error {{address space is larger than the maximum supported}}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
|
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
|
||||||
|
|
||||||
#define OPENCL_CONSTANT 8388354
|
int constant c[3] = {0};
|
||||||
int __attribute__((address_space(OPENCL_CONSTANT))) c[3] = {0};
|
|
||||||
|
|
||||||
void foo() {
|
void foo() {
|
||||||
c[0] = 1; //expected-error{{read-only variable is not assignable}}
|
c[0] = 1; //expected-error{{read-only variable is not assignable}}
|
Loading…
Reference in New Issue