[clang] 8008009 - [OpenCL] Initialize temporaries in the private address space
Author: Ole Strohm Date: 2021-09-13T12:56:04+01:00 New Revision: 8008009fd25bf51c2c85c612bfefec64e975bbe4 URL: https://github.com/llvm/llvm-project/commit/8008009fd25bf51c2c85c612bfefec64e975bbe4 DIFF: https://github.com/llvm/llvm-project/commit/8008009fd25bf51c2c85c612bfefec64e975bbe4.diff LOG: [OpenCL] Initialize temporaries in the private address space This patch fixes initializing temporaries, which are currently initialized without an address space, meaning that no constructor can ever be applicable. Now they will be constructed in the private addrspace. Fixes the second issue in PR43296. Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D107553 Added: clang/test/SemaOpenCLCXX/temporaries.clcpp Modified: clang/include/clang/Sema/Initialization.h clang/lib/Sema/SemaExprCXX.cpp clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp Removed: diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index 8feb66995f95c..4664861c4e32a 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -335,8 +335,15 @@ class alignas(8) InitializedEntity { } /// Create the initialization entity for a temporary. - static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) { -return InitializeTemporary(TypeInfo, TypeInfo->getType()); + static InitializedEntity InitializeTemporary(ASTContext , + TypeSourceInfo *TypeInfo) { +QualType Type = TypeInfo->getType(); +if (Context.getLangOpts().OpenCLCPlusPlus) { + assert(!Type.hasAddressSpace() && "Temporary already has address space!"); + Type = Context.getAddrSpaceQualType(Type, LangAS::opencl_private); +} + +return InitializeTemporary(TypeInfo, Type); } /// Create the initialization entity for a temporary. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7627ed4f37d52..e76c4509d7888 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1453,7 +1453,8 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, "List initialization must have initializer list as expression."); SourceRange FullRange = SourceRange(TyBeginLoc, RParenOrBraceLoc); - InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); + InitializedEntity Entity = + InitializedEntity::InitializeTemporary(Context, TInfo); InitializationKind Kind = Exprs.size() ? ListInitialization @@ -5290,7 +5291,8 @@ static bool evaluateTypeTrait(Sema , TypeTrait Kind, SourceLocation KWLoc, S, Sema::ExpressionEvaluationContext::Unevaluated); Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl()); -InitializedEntity To(InitializedEntity::InitializeTemporary(Args[0])); +InitializedEntity To( +InitializedEntity::InitializeTemporary(S.Context, Args[0])); InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc)); InitializationSequence Init(S, To, InitKind, ArgExprs); diff --git a/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp b/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp index 0605a48d0fe91..1b97484767b1a 100644 --- a/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp +++ b/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp @@ -32,6 +32,8 @@ kernel void k() { __local X lx; __private X x; + __private X tx = X(); + __private Y py; __constant Y cy1; // expected-error{{variable in constant address space must be initialized}} __constant Y cy2(1); // expected-error{{no matching constructor for initialization of '__constant Y'}} diff --git a/clang/test/SemaOpenCLCXX/temporaries.clcpp b/clang/test/SemaOpenCLCXX/temporaries.clcpp new file mode 100644 index 0..37d4f17183210 --- /dev/null +++ b/clang/test/SemaOpenCLCXX/temporaries.clcpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -pedantic -ast-dump | FileCheck %s + +struct X { + X() __private = default; +}; + +// CHECK: VarDecl {{.*}} gx +// CHECK: CXXTemporaryObjectExpr {{.*}} '__private X' +__global X gx = X(); + +void k() { + // CHECK: VarDecl {{.*}} x1 + // CHECK: CXXTemporaryObjectExpr {{.*}} '__private X' + X x1 = X(); + + // CHECK: VarDecl {{.*}} x2 + // CHECK: CXXConstructExpr {{.*}} 'const __private X' + const X x2; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 85255a0 - [C++][Sema] Ignore top-level qualifiers in casts
Author: Ole Strohm Date: 2021-07-05T12:22:08+01:00 New Revision: 85255a04e5729c03214c51177aa885c055f3e242 URL: https://github.com/llvm/llvm-project/commit/85255a04e5729c03214c51177aa885c055f3e242 DIFF: https://github.com/llvm/llvm-project/commit/85255a04e5729c03214c51177aa885c055f3e242.diff LOG: [C++][Sema] Ignore top-level qualifiers in casts Ignore top-level qualifiers in casts, which fixes issues in reinterpret_cast. This rule comes from [expr.type]/8.2.2 which explains that casting to a pr-qualified type should actually cast to the unqualified type. In C++ this is only done for types that aren't classes or arrays. Fixes: PR49221 Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D102689 Added: Modified: clang/lib/Sema/SemaCast.cpp clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp clang/test/SemaCXX/reinterpret-cast.cpp clang/test/SemaCXX/warn-reinterpret-base-class.cpp clang/test/SemaOpenCLCXX/addrspace_cast.clcpp clang/test/SemaOpenCLCXX/reinterpret-cast.clcpp Removed: diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 1e2113b58f81..869e414c7095 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -61,6 +61,15 @@ namespace { ValueKind(Expr::getValueKindForType(destType)), Kind(CK_Dependent), IsARCUnbridgedCast(false) { + // C++ [expr.type]/8.2.2: + // If a pr-value initially has the type cv-T, where T is a + // cv-unqualified non-class, non-array type, the type of the + // expression is adjusted to T prior to any further analysis. + if (!S.Context.getLangOpts().ObjC && !DestType->isRecordType() && + !DestType->isArrayType()) { +DestType = DestType.getUnqualifiedType(); + } + if (const BuiltinType *placeholder = src.get()->getType()->getAsPlaceholderType()) { PlaceholderKind = placeholder->getKind(); diff --git a/clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp b/clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp index 430223f337b7..3771e1b1e090 100644 --- a/clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp +++ b/clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp @@ -11,6 +11,17 @@ void bar(global int2 *in) { //CHECK: bitcast i64 %{{[0-9]+}} to <2 x i32> auto i2 = reinterpret_cast(l); + __private short s1; + // CHECK: %{{[0-9]+}} = load i16, i16* %s1, align 2 + // CHECK-NEXT: store i16 %{{[0-9]+}}, i16* %s2, align 2 + auto s2 = reinterpret_cast<__private short>(s1); + // CHECK: %{{[0-9]+}} = load i16, i16* %s1, align 2 + // CHECK-NEXT: store i16 %{{[0-9]+}}, i16* %s3, align 2 + auto s3 = reinterpret_cast(s1); + // CHECK: %{{[0-9]+}} = load i16, i16* %s1, align 2 + // CHECK-NEXT: store i16 %{{[0-9]+}}, i16* %s4, align 2 + auto s4 = reinterpret_cast<__global short>(s1); + int4 i4; //CHECK: bitcast <4 x i32> %{{[0-9]+}} to <2 x i64> auto l2 = reinterpret_cast(i4); diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp index 6cc46d8b0d9f..6a4bc9166544 100644 --- a/clang/test/SemaCXX/reinterpret-cast.cpp +++ b/clang/test/SemaCXX/reinterpret-cast.cpp @@ -25,6 +25,9 @@ void self_conversion() const int structure::*psi = 0; (void)reinterpret_cast(psi); + const int ci = 0; + (void)reinterpret_cast(i); + structure s; (void)reinterpret_cast(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}} @@ -68,6 +71,16 @@ void constness() (void)reinterpret_cast(ip); // Valid: T*** -> T2 const* const* const* (void)reinterpret_cast(ipppc); + + // C++ [expr.type]/8.2.2: + // If a pr-value initially has the type cv-T, where T is a + // cv-unqualified non-class, non-array type, the type of the + // expression is adjusted to T prior to any further analysis. + int i = 0; + // Valid: T -> T (top level const is ignored) + (void)reinterpret_cast(i); + // Valid: T* -> T* (top level const is ignored) + (void)reinterpret_cast(ip); } void fnptrs() diff --git a/clang/test/SemaCXX/warn-reinterpret-base-class.cpp b/clang/test/SemaCXX/warn-reinterpret-base-class.cpp index d73b4872117f..55bc777ce2e0 100644 --- a/clang/test/SemaCXX/warn-reinterpret-base-class.cpp +++ b/clang/test/SemaCXX/warn-reinterpret-base-class.cpp @@ -298,7 +298,7 @@ void diff erent_subobject_downcast(E *e, F *f, A *a) { #endif (void)reinterpret_cast(a); - // expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves diff erently from 'static_cast'}} + // expected-warning@+2 {{'reinterpret_cast' to class 'K' (aka 'const F *') from its base at non-zero offset 'E *' behaves diff erently from 'static_cast'}} // expected-note@+1 {{use 'static_cast' to adjust the pointer correctly while downcasting}} (void)reinterpret_cast(e);
[clang] 78d309c - [OpenCL] Fix qualifiers check on binding references to temporaries
Author: Ole Strohm Date: 2021-06-29T10:03:57+01:00 New Revision: 78d309ce197c30593450e792b0c2dc7a575f0050 URL: https://github.com/llvm/llvm-project/commit/78d309ce197c30593450e792b0c2dc7a575f0050 DIFF: https://github.com/llvm/llvm-project/commit/78d309ce197c30593450e792b0c2dc7a575f0050.diff LOG: [OpenCL] Fix qualifiers check on binding references to temporaries Fix the qualifiers check from PR49733. Fixes: PR49733 Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D103962 Added: Modified: clang/lib/Sema/SemaInit.cpp Removed: diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index f916299e4f560..240188f60592b 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5065,9 +5065,9 @@ static void TryReferenceInitializationCore(Sema , //than, cv2; otherwise, the program is ill-formed. unsigned T1CVRQuals = T1Quals.getCVRQualifiers(); unsigned T2CVRQuals = T2Quals.getCVRQualifiers(); - if ((RefRelationship == Sema::Ref_Related && - (T1CVRQuals | T2CVRQuals) != T1CVRQuals) || - !T1Quals.isAddressSpaceSupersetOf(T2Quals)) { + if (RefRelationship == Sema::Ref_Related && + ((T1CVRQuals | T2CVRQuals) != T1CVRQuals || + !T1Quals.isAddressSpaceSupersetOf(T2Quals))) { Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers); return; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b102e68 - [OpenCL] Fix overloading resolution of addrspace constructors
Author: Ole Strohm Date: 2021-06-11T11:12:33+01:00 New Revision: b102e6880ab06654f945284a520f68c099732f44 URL: https://github.com/llvm/llvm-project/commit/b102e6880ab06654f945284a520f68c099732f44 DIFF: https://github.com/llvm/llvm-project/commit/b102e6880ab06654f945284a520f68c099732f44.diff LOG: [OpenCL] Fix overloading resolution of addrspace constructors This fixes the prioritization of address spaces when choosing a constructor, stopping them from being considered equally good, which made the construction of types that could be constructed by more than one of the constructors. It does this by preferring the most specific address space, which is decided by seeing if one of the address spaces is a superset of the other, and preferring the other. Fixes: PR50329 Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D102850 Added: Modified: clang/lib/Sema/SemaOverload.cpp clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp Removed: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 4b6c3f3658a7f..2801c3cff8afc 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -9867,6 +9867,23 @@ bool clang::isBetterOverloadCandidate( S.IdentifyCUDAPreference(Caller, Cand2.Function); } + // General member function overloading is handled above, so this only handles + // constructors with address spaces. + // This only handles address spaces since C++ has no other + // qualifier that can be used with constructors. + const auto *CD1 = dyn_cast_or_null(Cand1.Function); + const auto *CD2 = dyn_cast_or_null(Cand2.Function); + if (CD1 && CD2) { +LangAS AS1 = CD1->getMethodQualifiers().getAddressSpace(); +LangAS AS2 = CD2->getMethodQualifiers().getAddressSpace(); +if (AS1 != AS2) { + if (Qualifiers::isAddressSpaceSupersetOf(AS2, AS1)) +return true; + if (Qualifiers::isAddressSpaceSupersetOf(AS2, AS1)) +return false; +} + } + return false; } diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp b/clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp index a5e41950649df..c0913f484f5e3 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp +++ b/clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp @@ -11,8 +11,7 @@ struct X { int x; // Local variables are handled in local_addrspace_init.clcpp - // FIXME: __private and __generic constructors clash for __private variable - // X() /*__generic*/ = default; + X() /*__generic*/ : x(0) {} X() __private : x(0) {} X() __global : x(0) {} constexpr X() __constant : x(0) {} @@ -30,7 +29,7 @@ __global X gx; // CHECK: @_ZZ1kE3cx2 = internal addrspace(2) constant %struct.X { i32 1 } kernel void k() { - // Check that the constructor for px is executed + // Check that the constructor for px calls the __private constructor. // CHECK: %px = alloca %struct.X // CHECK-NEXT: call spir_func void @_ZN1XC1Ev(%struct.X* {{.*}}%px) __private X px; diff --git a/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp b/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp index 9154d579a9b4a..0605a48d0fe91 100644 --- a/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp +++ b/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp @@ -1,14 +1,24 @@ -// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only +// RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s __constant int g1; // expected-error {{variable in constant address space must be initialized}} __constant int g2 = 0; struct X { int x; +//CHECK: CXXConstructorDecl +//CHECK-NOT: used +//CHECK-SAME: X 'void (){{.*}} __generic' + X() /*__generic*/ : x(0) {} +//CHECK: CXXConstructorDecl {{.*}} used X 'void (){{.*}} __private' + X() __private : x(0) {} +//CHECK: CXXConstructorDecl {{.*}} used X 'void (){{.*}} __global' + X() __global : x(0) {} constexpr X() __constant : x(0) {} constexpr X(int x) __constant : x(x) {} }; +__global X gx; + //expected-note@+2{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const __generic Y' for 1st argument}} //expected-note@+1{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to '__generic Y' for 1st argument}} struct Y { @@ -20,6 +30,7 @@ kernel void k() { __constant X cx1; __constant X cx2(1); __local X lx; + __private X x; __private Y py; __constant Y cy1; // expected-error{{variable in constant address space must be initialized}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ac677e6 - [OpenCL] Relax test implicit members in C++ for OpenCL
Author: Ole Strohm Date: 2021-06-10T10:18:52+01:00 New Revision: ac677e69bdfc84fc64bfbc83977282d5c5223206 URL: https://github.com/llvm/llvm-project/commit/ac677e69bdfc84fc64bfbc83977282d5c5223206 DIFF: https://github.com/llvm/llvm-project/commit/ac677e69bdfc84fc64bfbc83977282d5c5223206.diff LOG: [OpenCL] Relax test implicit members in C++ for OpenCL Addresses the issue from a comment in D103252 Relaxes the test to account for some targets with added attributes to inside the pattern. Added: Modified: clang/test/AST/ast-dump-implicit-members.clcpp Removed: diff --git a/clang/test/AST/ast-dump-implicit-members.clcpp b/clang/test/AST/ast-dump-implicit-members.clcpp index 5e1eb7c48c2a9..f80211e1f33d4 100644 --- a/clang/test/AST/ast-dump-implicit-members.clcpp +++ b/clang/test/AST/ast-dump-implicit-members.clcpp @@ -7,8 +7,8 @@ void f() { i = i; } -// CHECK: CXXConstructorDecl {{.*}} implicit used constexpr S 'void () __generic noexcept' -// CHECK: CXXConstructorDecl {{.*}} implicit constexpr S 'void (const __generic S &) __generic' -// CHECK: CXXConstructorDecl {{.*}} implicit constexpr S 'void (__generic S &&) __generic' -// CHECK: CXXMethodDecl {{.*}} implicit used constexpr operator= '__generic S &(const __generic S &) __generic noexcept' -// CHECK: CXXMethodDecl {{.*}} implicit constexpr operator= '__generic S &(__generic S &&) __generic' +// CHECK: CXXConstructorDecl {{.*}} implicit used constexpr S 'void (){{.*}} __generic noexcept' +// CHECK: CXXConstructorDecl {{.*}} implicit constexpr S 'void (const __generic S &){{.*}} __generic' +// CHECK: CXXConstructorDecl {{.*}} implicit constexpr S 'void (__generic S &&){{.*}} __generic' +// CHECK: CXXMethodDecl {{.*}} implicit used constexpr operator= '__generic S &(const __generic S &){{.*}} __generic noexcept' +// CHECK: CXXMethodDecl {{.*}} implicit constexpr operator= '__generic S &(__generic S &&){{.*}} __generic' ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 438cf55 - [OpenCL] Fix missing addrspace on implicit move assignment operator
Author: Ole Strohm Date: 2021-06-07T09:37:53+01:00 New Revision: 438cf5577e720f84d493a272c5a1cbaf6ce19e51 URL: https://github.com/llvm/llvm-project/commit/438cf5577e720f84d493a272c5a1cbaf6ce19e51 DIFF: https://github.com/llvm/llvm-project/commit/438cf5577e720f84d493a272c5a1cbaf6ce19e51.diff LOG: [OpenCL] Fix missing addrspace on implicit move assignment operator This fixes the missing address space on `this` in the implicit move assignment operator. The function called here is an abstraction around the lines that have been removed which also sets the address space correctly. This is copied from CopyConstructor, CopyAssignment and MoveConstructor, all of which use this function, and now MoveAssignment does too. Fixes: PR50259 Reviewed By: svenvh Differential Revision: https://reviews.llvm.org/D103252 Added: clang/test/AST/ast-dump-implicit-members.clcpp Modified: clang/lib/Sema/SemaDeclCXX.cpp Removed: diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f6c907b2f98a1..3fffcd33ac50f 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -14344,10 +14344,7 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) { /* Diagnose */ false); } - // Build an exception specification pointing back at this member. - FunctionProtoType::ExtProtoInfo EPI = - getImplicitMethodEPI(*this, MoveAssignment); - MoveAssignment->setType(Context.getFunctionType(RetType, ArgType, EPI)); + setupImplicitSpecialMemberType(MoveAssignment, RetType, ArgType); // Add the parameter to the operator. ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveAssignment, diff --git a/clang/test/AST/ast-dump-implicit-members.clcpp b/clang/test/AST/ast-dump-implicit-members.clcpp new file mode 100644 index 0..5e1eb7c48c2a9 --- /dev/null +++ b/clang/test/AST/ast-dump-implicit-members.clcpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -ast-dump -ast-dump-filter S | FileCheck -strict-whitespace %s + +struct S {}; + +void f() { +S i; +i = i; +} + +// CHECK: CXXConstructorDecl {{.*}} implicit used constexpr S 'void () __generic noexcept' +// CHECK: CXXConstructorDecl {{.*}} implicit constexpr S 'void (const __generic S &) __generic' +// CHECK: CXXConstructorDecl {{.*}} implicit constexpr S 'void (__generic S &&) __generic' +// CHECK: CXXMethodDecl {{.*}} implicit used constexpr operator= '__generic S &(const __generic S &) __generic noexcept' +// CHECK: CXXMethodDecl {{.*}} implicit constexpr operator= '__generic S &(__generic S &&) __generic' ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 94b0aec - [OpenCL] Fix ICE with invalid use of half
Author: Ole Strohm Date: 2021-06-01T13:43:07+01:00 New Revision: 94b0aec0f5c6b4f6a27cf3a542f795bbba72e851 URL: https://github.com/llvm/llvm-project/commit/94b0aec0f5c6b4f6a27cf3a542f795bbba72e851 DIFF: https://github.com/llvm/llvm-project/commit/94b0aec0f5c6b4f6a27cf3a542f795bbba72e851.diff LOG: [OpenCL] Fix ICE with invalid use of half Because half is limited to the `cl_khr_fp16` extension being enabled, `DefaultLvalueConversion` can fail when it's not enabled. The original assumption that it will never fail is therefore wrong now. Fixes: PR47976 Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D103175 Added: clang/test/SemaOpenCLCXX/half.clcpp Modified: clang/lib/Sema/SemaExprCXX.cpp Removed: diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b31c484b11700..75ebeaea1072c 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4193,7 +4193,9 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_Lvalue_To_Rvalue: { assert(From->getObjectKind() != OK_ObjCProperty); ExprResult FromRes = DefaultLvalueConversion(From); -assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!"); +if (FromRes.isInvalid()) + return ExprError(); + From = FromRes.get(); FromType = From->getType(); break; diff --git a/clang/test/SemaOpenCLCXX/half.clcpp b/clang/test/SemaOpenCLCXX/half.clcpp new file mode 100644 index 0..bcb422fe58bf3 --- /dev/null +++ b/clang/test/SemaOpenCLCXX/half.clcpp @@ -0,0 +1,15 @@ +//RUN: %clang_cc1 %s -triple spir -verify -fsyntax-only + +#pragma OPENCL EXTENSION cl_khr_fp16 : disable + +typedef half half2 __attribute__((ext_vector_type(2))); + +half f(half2 h2) { // expected-error{{declaring function return value of type 'half' is not allowed ; did you forget * ?}} +return h2.s0; // expected-error{{loading directly from pointer to type '__private half' requires cl_khr_fp16. Use vector data load builtin functions instead}} +} + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +half f(half2 h2) { +return h2.s0; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 642d2f0 - [OpenCL] Fix initialization of __constant constructors without arguments
Author: Ole Strohm Date: 2021-05-18T10:59:53+01:00 New Revision: 642d2f000b26821010793ea1ea6a38a6695fc864 URL: https://github.com/llvm/llvm-project/commit/642d2f000b26821010793ea1ea6a38a6695fc864 DIFF: https://github.com/llvm/llvm-project/commit/642d2f000b26821010793ea1ea6a38a6695fc864.diff LOG: [OpenCL] Fix initialization of __constant constructors without arguments This fixes the initialization of objects in the __constant address space that occurs when declaring the object. Fixes part of PR42566 Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D102248 Added: clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp Modified: clang/lib/Sema/SemaDecl.cpp Removed: diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index db267089be965..c4db147e7efde 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12635,9 +12635,21 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { if (!Var->isInvalidDecl() && Var->getType().getAddressSpace() == LangAS::opencl_constant && Var->getStorageClass() != SC_Extern && !Var->getInit()) { - Diag(Var->getLocation(), diag::err_opencl_constant_no_init); - Var->setInvalidDecl(); - return; + bool HasConstExprDefaultConstructor = false; + if (CXXRecordDecl *RD = Var->getType()->getAsCXXRecordDecl()) { +for (auto *Ctor : RD->ctors()) { + if (Ctor->isConstexpr() && Ctor->getNumParams() == 0 && + Ctor->getMethodQualifiers().getAddressSpace() == + LangAS::opencl_constant) { +HasConstExprDefaultConstructor = true; + } +} + } + if (!HasConstExprDefaultConstructor) { +Diag(Var->getLocation(), diag::err_opencl_constant_no_init); +Var->setInvalidDecl(); +return; + } } if (!Var->isInvalidDecl() && RealDecl->hasAttr()) { diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp b/clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp new file mode 100644 index 0..5d81bc57603e7 --- /dev/null +++ b/clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -O0 -triple spir-unknown-unknown | FileCheck %s + +// CHECK: %struct.X = type { i32 } + +// CHECK: @ci = dso_local addrspace(2) constant i32 0 +// CHECK: @gi = dso_local addrspace(1) global i32 0 +__constant int ci = 0; +__global int gi = 0; + +struct X { + int x; + + // Local variables are handled in local_addrspace_init.clcpp + // FIXME: __private and __generic constructors clash for __private variable + // X() /*__generic*/ = default; + X() __private : x(0) {} + X() __global : x(0) {} + constexpr X() __constant : x(0) {} + constexpr X(int x) __constant : x(x) {} +}; + +// CHECK: @cx1 = dso_local addrspace(2) constant %struct.X zeroinitializer +// CHECK: @cx2 = dso_local addrspace(2) constant %struct.X { i32 1 } +// CHECK: @gx = dso_local addrspace(1) global %struct.X zeroinitializer +__constant X cx1; +__constant X cx2(1); +__global X gx; + +// CHECK: @_ZZ1kE3cx1 = internal addrspace(2) constant %struct.X zeroinitializer +// CHECK: @_ZZ1kE3cx2 = internal addrspace(2) constant %struct.X { i32 1 } + +kernel void k() { + // Check that the constructor for px is executed + // CHECK: %px = alloca %struct.X + // CHECK-NEXT: call spir_func void @_ZN1XC1Ev(%struct.X* {{.*}}%px) + __private X px; + + __constant X cx1; + __constant X cx2(1); + // CHECK-NEXT: ret void +} diff --git a/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp b/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp new file mode 100644 index 0..9154d579a9b4a --- /dev/null +++ b/clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only + +__constant int g1; // expected-error {{variable in constant address space must be initialized}} +__constant int g2 = 0; + +struct X { + int x; + constexpr X() __constant : x(0) {} + constexpr X(int x) __constant : x(x) {} +}; + +//expected-note@+2{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const __generic Y' for 1st argument}} +//expected-note@+1{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to '__generic Y' for 1st argument}} +struct Y { + int y; + Y() __generic = default; // expected-note{{candidate constructor not viable: requires 0 arguments, but 1 was provided}} +}; + +kernel void k() { + __constant X cx1; + __constant X cx2(1); + __local X lx; + + __private Y py; + __constant Y cy1; // expected-error{{variable in constant address space must be initialized}} + __constant Y cy2(1); // expected-error{{no matching constructor for
[clang] 66b112d - [OpenCL] Fix reinterpret_cast of vectors
Author: Ole Strohm Date: 2021-05-17T12:42:21+01:00 New Revision: 66b112d624a549489fa0af131cf7b632c6181424 URL: https://github.com/llvm/llvm-project/commit/66b112d624a549489fa0af131cf7b632c6181424 DIFF: https://github.com/llvm/llvm-project/commit/66b112d624a549489fa0af131cf7b632c6181424.diff LOG: [OpenCL] Fix reinterpret_cast of vectors Fixes issues with vectors in reinterpret_cast in C++ for OpenCL and adds tests to make sure they both pass without errors and generate the correct code. Fixes: PR47977 Reviewed By: Anastasia Differential Revision: https://reviews.llvm.org/D101519 Added: clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp clang/test/SemaOpenCLCXX/reinterpret-cast.clcpp Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaCast.cpp clang/lib/Sema/SemaExpr.cpp Removed: diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 3a8f41196cc4a..b6143d1d31789 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11640,6 +11640,7 @@ class Sema final { bool areMatrixTypesOfTheSameDimension(QualType srcTy, QualType destTy); + bool areVectorTypesSameSize(QualType srcType, QualType destType); bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType); bool isLaxVectorConversion(QualType srcType, QualType destType); diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 7ed62cc8990eb..439b128e90ea4 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -2335,6 +2335,16 @@ static TryCastResult TryReinterpretCast(Sema , ExprResult , return TC_Success; } +if (Self.LangOpts.OpenCL && !CStyle) { + if (DestType->isExtVectorType() || SrcType->isExtVectorType()) { +// FIXME: Allow for reinterpret cast between 3 and 4 element vectors +if (Self.areVectorTypesSameSize(SrcType, DestType)) { + Kind = CK_BitCast; + return TC_Success; +} + } +} + // Otherwise, pick a reasonable diagnostic. if (!destIsVector) msg = diag::err_bad_cxx_cast_vector_to_scalar_ diff erent_size; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 948d5eddb43b3..51df757071457 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7341,6 +7341,25 @@ bool Sema::areMatrixTypesOfTheSameDimension(QualType srcTy, QualType destTy) { matSrcType->getNumColumns() == matDestType->getNumColumns(); } +bool Sema::areVectorTypesSameSize(QualType SrcTy, QualType DestTy) { + assert(DestTy->isVectorType() || SrcTy->isVectorType()); + + uint64_t SrcLen, DestLen; + QualType SrcEltTy, DestEltTy; + if (!breakDownVectorType(SrcTy, SrcLen, SrcEltTy)) +return false; + if (!breakDownVectorType(DestTy, DestLen, DestEltTy)) +return false; + + // ASTContext::getTypeSize will return the size rounded up to a + // power of 2, so instead of using that, we need to use the raw + // element size multiplied by the element count. + uint64_t SrcEltSize = Context.getTypeSize(SrcEltTy); + uint64_t DestEltSize = Context.getTypeSize(DestEltTy); + + return (SrcLen * SrcEltSize == DestLen * DestEltSize); +} + /// Are the two types lax-compatible vector types? That is, given /// that one of them is a vector, do they have equal storage sizes, /// where the storage size is the number of elements times the element @@ -7359,18 +7378,7 @@ bool Sema::areLaxCompatibleVectorTypes(QualType srcTy, QualType destTy) { if (srcTy->isScalarType() && destTy->isExtVectorType()) return false; if (destTy->isScalarType() && srcTy->isExtVectorType()) return false; - uint64_t srcLen, destLen; - QualType srcEltTy, destEltTy; - if (!breakDownVectorType(srcTy, srcLen, srcEltTy)) return false; - if (!breakDownVectorType(destTy, destLen, destEltTy)) return false; - - // ASTContext::getTypeSize will return the size rounded up to a - // power of 2, so instead of using that, we need to use the raw - // element size multiplied by the element count. - uint64_t srcEltSize = Context.getTypeSize(srcEltTy); - uint64_t destEltSize = Context.getTypeSize(destEltTy); - - return (srcLen * srcEltSize == destLen * destEltSize); + return areVectorTypesSameSize(srcTy, destTy); } /// Is this a legal conversion between two types, one of which is diff --git a/clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp b/clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp new file mode 100644 index 0..430223f337b77 --- /dev/null +++ b/clang/test/CodeGenOpenCLCXX/reinterpret_cast.clcpp @@ -0,0 +1,17 @@ +//RUN: %clang_cc1 %s -triple spir -emit-llvm -O0 -o - | FileCheck %s + +typedef int int2 __attribute__((ext_vector_type(2))); +typedef int int4 __attribute__((ext_vector_type(4))); +typedef long long2 __attribute__((ext_vector_type(2))); + +//CHECK-LABEL: define{{.*}}
[clang] 7d20f70 - [OpenCL] [NFC] Fixed underline being too short in rst
Author: Ole Strohm Date: 2021-05-11T09:45:28+01:00 New Revision: 7d20f709ea6da8442a153beda7ecdda07440f046 URL: https://github.com/llvm/llvm-project/commit/7d20f709ea6da8442a153beda7ecdda07440f046 DIFF: https://github.com/llvm/llvm-project/commit/7d20f709ea6da8442a153beda7ecdda07440f046.diff LOG: [OpenCL] [NFC] Fixed underline being too short in rst Added: Modified: clang/docs/LanguageExtensions.rst Removed: diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index bdb5b3adf39f..235bcac8f00f 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1814,7 +1814,7 @@ supporting the variadic arguments e.g. majority of CPU targets. void bar(int a, ...); // error - variadic prototype is not allowed ``__cl_clang_non_portable_kernel_param_types`` -- +-- With this extension it is possible to enable the use of some restricted types in kernel parameters specified in `C++ for OpenCL v1.0 s2.4 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f372ff1 - [NFC] (test commit) Changed example invocation of C++ for OpenCL
Author: Ole Strohm Date: 2021-05-07T12:31:37+01:00 New Revision: f372ff17f74f99f5e1c021a9c919b33c4caf38d9 URL: https://github.com/llvm/llvm-project/commit/f372ff17f74f99f5e1c021a9c919b33c4caf38d9 DIFF: https://github.com/llvm/llvm-project/commit/f372ff17f74f99f5e1c021a9c919b33c4caf38d9.diff LOG: [NFC] (test commit) Changed example invocation of C++ for OpenCL Added: Modified: clang/docs/OpenCLSupport.rst Removed: diff --git a/clang/docs/OpenCLSupport.rst b/clang/docs/OpenCLSupport.rst index 5bde2c332022f..fa719c8bdf9f5 100644 --- a/clang/docs/OpenCLSupport.rst +++ b/clang/docs/OpenCLSupport.rst @@ -432,7 +432,7 @@ The possible clang invocation to compile the example is as follows: .. code-block:: console - $ clang -cl-std=clc++ -I/include test.cl + $ clang -I/include test.clcpp Note that `type_traits` is a header only library and therefore no extra linking step against the standard libraries is required. See full example ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits