diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -151,6 +151,9 @@ def err_opencl_unknown_type_specifier : Error< "%select{OpenCL C|C++ for OpenCL}0 version %1 does not support the " "'%2' %select{type qualifier|storage class specifier}3">; +def err_opencl_type_specifier_requires : Error< + "%select{type qualifier|storage class specifier}0 '%1' requires " + "OpenCL C 2.0 or later and a feature support">; def warn_unknown_attribute_ignored : Warning< "unknown attribute %0 ignored">, InGroup; diff --git a/clang/lib/Basic/OpenCLOptions.cpp b/clang/lib/Basic/OpenCLOptions.cpp --- a/clang/lib/Basic/OpenCLOptions.cpp +++ b/clang/lib/Basic/OpenCLOptions.cpp @@ -111,7 +111,8 @@ // Feature pairs. First feature in a pair requires the second one to be // supported. static const llvm::StringMap DependentFeaturesMap = { - {"__opencl_c_read_write_images", "__opencl_c_images"}}; + {"__opencl_c_read_write_images", "__opencl_c_images"}, + {"__opencl_c_pipes", "__opencl_c_generic_address_space"}}; auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts(); diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -400,14 +400,18 @@ // OpenCL C v3.0 s6.7.5 - The generic address space requires support for // OpenCL C 2.0 or OpenCL C 3.0 with the __opencl_c_generic_address_space // feature - // FIXME: OpenCLGenericAddressSpace is also defined in setLangDefaults() + // OpenCL C v3.0 s6.2.1 - OpenCL pipes require support of OpenCL C 2.0 + // or later and __opencl_c_pipes feature + // FIXME: These language options are also defined in setLangDefaults() // for OpenCL C 2.0 but with no access to target capabilities. Target - // should be immutable once created and thus this language option needs + // should be immutable once created and thus these language options need // to be defined only once. if (Opts.OpenCLVersion >= 300) { const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts(); Opts.OpenCLGenericAddressSpace = hasFeatureEnabled( OpenCLFeaturesMap, "__opencl_c_generic_address_space"); + Opts.OpenCLPipe = + hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes"); } } diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3952,8 +3952,12 @@ Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); Tok.setKind(tok::identifier); goto DoneWithDeclSpec; - } - isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy); + } else if (!getLangOpts().OpenCLPipe) { + DiagID = diag::err_opencl_type_specifier_requires; + PrevSpec = Tok.getIdentifierInfo()->getNameStart(); + isInvalid = true; + } else + isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy); break; // We only need to enumerate each image type once. #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) @@ -4075,7 +4079,7 @@ // OpenCL v3.0 introduces __opencl_c_generic_address_space // feature macro to indicate if generic address space is supported if (!Actions.getLangOpts().OpenCLGenericAddressSpace) { - DiagID = diag::err_opencl_unknown_type_specifier; + DiagID = diag::err_opencl_type_specifier_requires; PrevSpec = Tok.getIdentifierInfo()->getNameStart(); isInvalid = true; break; @@ -4141,6 +4145,8 @@ Diag(Loc, DiagID) << getLangOpts().OpenCLCPlusPlus << getLangOpts().getOpenCLVersionTuple().getAsString() << PrevSpec << isStorageClass; + } else if (DiagID == diag::err_opencl_type_specifier_requires) { + Diag(Loc, DiagID) << isStorageClass << PrevSpec; } else Diag(Loc, DiagID) << PrevSpec; } @@ -5126,8 +5132,10 @@ switch (Tok.getKind()) { default: return false; + // OpenCL 2.0 and later define this keyword. case tok::kw_pipe: - return getLangOpts().OpenCLPipe; + return (getLangOpts().OpenCL && getLangOpts().OpenCLVersion >= 200) || + getLangOpts().OpenCLCPlusPlus; case tok::identifier: // foo::bar // Unfortunate hack to support "Class.factoryMethod" notation. @@ -5656,7 +5664,9 @@ if (Kind == tok::star || Kind == tok::caret) return true; - if (Kind == tok::kw_pipe && Lang.OpenCLPipe) + // OpenCL 2.0 and later define this keyword. + if (Kind == tok::kw_pipe && + ((Lang.OpenCL && Lang.OpenCLVersion >= 200) || Lang.OpenCLCPlusPlus)) return true; if (!Lang.CPlusPlus) diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -327,7 +327,8 @@ if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) { addImplicitTypedef("clk_event_t", Context.OCLClkEventTy); addImplicitTypedef("queue_t", Context.OCLQueueTy); - addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy); + if (getLangOpts().OpenCLPipe) + addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy); addImplicitTypedef("atomic_int", Context.getAtomicType(Context.IntTy)); addImplicitTypedef("atomic_uint", Context.getAtomicType(Context.UnsignedIntTy)); diff --git a/clang/test/CodeGenOpenCL/address-spaces-mangling.cl b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl --- a/clang/test/CodeGenOpenCL/address-spaces-mangling.cl +++ b/clang/test/CodeGenOpenCL/address-spaces-mangling.cl @@ -9,7 +9,7 @@ // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL1.2 -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s // RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=+__opencl_c_generic_address_space -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space,-__opencl_c_pipes -emit-llvm -o - | FileCheck -check-prefix=OCL-12 %s // We can't name this f as private is equivalent to default // no specifier given address space so we get multiple definition diff --git a/clang/test/CodeGenOpenCL/address-spaces.cl b/clang/test/CodeGenOpenCL/address-spaces.cl --- a/clang/test/CodeGenOpenCL/address-spaces.cl +++ b/clang/test/CodeGenOpenCL/address-spaces.cl @@ -1,5 +1,5 @@ // RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR -// RUN: %clang_cc1 %s -O0 -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,SPIR +// RUN: %clang_cc1 %s -O0 -cl-std=CL3.0 -cl-ext=-__opencl_c_generic_address_space,-__opencl_c_pipes -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-prefixes=CL20,CL20SPIR // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s // RUN: %clang_cc1 %s -O0 -triple amdgcn-amd-amdhsa -cl-std=CL3.0 -emit-llvm -o - | FileCheck --check-prefixes=CHECK,AMDGCN %s diff --git a/clang/test/CodeGenOpenCL/pipe_builtin.cl b/clang/test/CodeGenOpenCL/pipe_builtin.cl --- a/clang/test/CodeGenOpenCL/pipe_builtin.cl +++ b/clang/test/CodeGenOpenCL/pipe_builtin.cl @@ -71,3 +71,16 @@ // CHECK: call i32 @__get_pipe_max_packets_wo(%opencl.pipe_wo_t* %{{.*}}, i32 4, i32 4) *ptr = get_pipe_max_packets(p); } + +struct Person { + const char *Name; + bool isFemale; + int ID; +}; + +void test9(global struct Person *SDst, read_only pipe struct Person SPipe) { + // CHECK: call i32 @__read_pipe_2(%opencl.pipe_ro_t* %{{.*}}, i8* %{{.*}}, i32 16, i32 8) + read_pipe (SPipe, SDst); + // CHECK: call i32 @__read_pipe_2(%opencl.pipe_ro_t* %{{.*}}, i8* %{{.*}}, i32 16, i32 8) + read_pipe (SPipe, SDst); +} diff --git a/clang/test/CodeGenOpenCL/pipe_types.cl b/clang/test/CodeGenOpenCL/pipe_types.cl --- a/clang/test/CodeGenOpenCL/pipe_types.cl +++ b/clang/test/CodeGenOpenCL/pipe_types.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -O0 -cl-std=CL3.0 -cl-ext=+__opencl_c_pipes,+__opencl_c_generic_address_space -o - %s | FileCheck %s // CHECK: %opencl.pipe_ro_t = type opaque // CHECK: %opencl.pipe_wo_t = type opaque @@ -31,18 +32,3 @@ kernel void test6(MyPipe p) { // CHECK: define{{.*}} spir_kernel void @test6(%opencl.pipe_ro_t* %p) } - -struct Person { - const char *Name; - bool isFemale; - int ID; -}; - -void test_reserved_read_pipe(global struct Person *SDst, - read_only pipe struct Person SPipe) { -// CHECK: define{{.*}} void @test_reserved_read_pipe - read_pipe (SPipe, SDst); - // CHECK: call i32 @__read_pipe_2(%opencl.pipe_ro_t* %{{.*}}, i8* %{{.*}}, i32 16, i32 8) - read_pipe (SPipe, SDst); - // CHECK: call i32 @__read_pipe_2(%opencl.pipe_ro_t* %{{.*}}, i8* %{{.*}}, i32 16, i32 8) -} diff --git a/clang/test/CodeGenOpenCL/pipe_types_mangling.cl b/clang/test/CodeGenOpenCL/pipe_types_mangling.cl --- a/clang/test/CodeGenOpenCL/pipe_types_mangling.cl +++ b/clang/test/CodeGenOpenCL/pipe_types_mangling.cl @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -triple x86_64-unknown-windows-pc -emit-llvm -O0 -cl-std=clc++ -o - %s -DWIN| FileCheck %s --check-prefixes=WINDOWS // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -O0 -cl-std=CL2.0 -o - %s | FileCheck %s --check-prefixes=LINUX // RUN: %clang_cc1 -triple x86_64-unknown-windows-pc -emit-llvm -O0 -cl-std=CL2.0 -o - %s -DWIN| FileCheck %s --check-prefixes=OCLWINDOWS +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -O0 -cl-std=CL3.0 -cl-ext=+__opencl_c_pipes,+__opencl_c_generic_address_space -o - %s | FileCheck %s --check-prefixes=LINUX +// RUN: %clang_cc1 -triple x86_64-unknown-windows-pc -emit-llvm -O0 -cl-std=CL3.0 -cl-ext=+__opencl_c_pipes,+__opencl_c_generic_address_space -o - %s -DWIN | FileCheck %s --check-prefixes=OCLWINDOWS typedef unsigned char __attribute__((ext_vector_type(3))) uchar3; typedef int __attribute__((ext_vector_type(4))) int4; diff --git a/clang/test/Misc/opencl-c-3.0.incorrect_options.cl b/clang/test/Misc/opencl-c-3.0.incorrect_options.cl --- a/clang/test/Misc/opencl-c-3.0.incorrect_options.cl +++ b/clang/test/Misc/opencl-c-3.0.incorrect_options.cl @@ -1,6 +1,8 @@ // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=-__opencl_c_fp64,+cl_khr_fp64 %s 2>&1 | FileCheck -check-prefix=CHECK-FP64 %s // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_fp64,-cl_khr_fp64 %s 2>&1 | FileCheck -check-prefix=CHECK-FP64 %s // RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_read_write_images,-__opencl_c_images %s 2>&1 | FileCheck -check-prefix=CHECK-READ-WRITE-IMAGES %s +// RUN: not %clang_cc1 -cl-std=CL3.0 -triple spir-unknown-unknown -cl-ext=+__opencl_c_pipes,-__opencl_c_generic_address_space %s 2>&1 | FileCheck -check-prefix=CHECK-PIPES %s // CHECK-FP64: error: options cl_khr_fp64 and __opencl_c_fp64 are set to different values // CHECK-READ-WRITE-IMAGES: error: feature __opencl_c_read_write_images requires support of __opencl_c_images feature +// CHECK-PIPES: error: feature __opencl_c_pipes requires support of __opencl_c_generic_address_space diff --git a/clang/test/Parser/opencl-cl20.cl b/clang/test/Parser/opencl-cl20.cl --- a/clang/test/Parser/opencl-cl20.cl +++ b/clang/test/Parser/opencl-cl20.cl @@ -10,9 +10,9 @@ return var; } #ifndef CL20 -// expected-error@-5 {{OpenCL C version 1.0 does not support the '__generic' type qualifier}} -// expected-error@-6 {{OpenCL C version 1.0 does not support the '__generic' type qualifier}} -// expected-error@-6 {{OpenCL C version 1.0 does not support the '__generic' type qualifier}} +// expected-error@-5 {{type qualifier '__generic' requires OpenCL C 2.0 or later and a feature support}} +// expected-error@-6 {{type qualifier '__generic' requires OpenCL C 2.0 or later and a feature support}} +// expected-error@-6 {{type qualifier '__generic' requires OpenCL C 2.0 or later and a feature support}} #endif generic int * generic_test(generic int *arg) { @@ -20,7 +20,7 @@ return var; } #ifndef CL20 -// expected-error@-5 {{OpenCL C version 1.0 does not support the 'generic' type qualifier}} -// expected-error@-6 {{OpenCL C version 1.0 does not support the 'generic' type qualifier}} -// expected-error@-6 {{OpenCL C version 1.0 does not support the 'generic' type qualifier}} +// expected-error@-5 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} +// expected-error@-6 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} +// expected-error@-6 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} #endif diff --git a/clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl b/clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl --- a/clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl +++ b/clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl @@ -1,9 +1,23 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2 +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_pipes,-__opencl_c_generic_address_space void foo(read_only pipe int p); -// expected-warning@-1 {{type specifier missing, defaults to 'int'}} -// expected-error@-2 {{access qualifier can only be used for pipe and image type}} -// expected-error@-3 {{expected ')'}} expected-note@-3 {{to match this '('}} +#if __OPENCL_C_VERSION__ > 120 +// expected-error@-2 {{type qualifier 'pipe' requires OpenCL C 2.0 or later and a feature support}} +// expected-error@-3 {{access qualifier can only be used for pipe and image type}} +#else +// expected-warning@-5 {{type specifier missing, defaults to 'int'}} +// expected-error@-6 {{access qualifier can only be used for pipe and image type}} +// expected-error@-7 {{expected ')'}} expected-note@-7 {{to match this '('}} +#endif // 'pipe' should be accepted as an identifier. typedef int pipe; +#if __OPENCL_C_VERSION__ > 120 +// expected-error@-2 {{type qualifier 'pipe' requires OpenCL C 2.0 or later and a feature support}} +// expected-warning@-3 {{typedef requires a name}} +#endif + +void bar() { + reserve_id_t r; // expected-error {{use of undeclared identifier 'reserve_id_t'}} +} diff --git a/clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl b/clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl --- a/clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl +++ b/clang/test/SemaOpenCL/invalid-pipes-cl2.0.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_pipes,+__opencl_c_generic_address_space // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=clc++ global pipe int gp; // expected-error {{type '__global read_only pipe int' can only be used as a function parameter in OpenCL}} diff --git a/clang/test/SemaOpenCL/storageclass.cl b/clang/test/SemaOpenCL/storageclass.cl --- a/clang/test/SemaOpenCL/storageclass.cl +++ b/clang/test/SemaOpenCL/storageclass.cl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2 -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space,-__opencl_c_pipes +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables,-__opencl_c_generic_address_space,-__opencl_c_pipes // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=-__opencl_c_program_scope_global_variables,+__opencl_c_generic_address_space // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL3.0 -cl-ext=+__opencl_c_program_scope_global_variables,+__opencl_c_generic_address_space static constant int G1 = 0; @@ -44,11 +44,11 @@ static generic float g_generic_static_var = 0; #if (__OPENCL_C_VERSION__ < 300) -// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} +// expected-error@-2 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} // expected-error@-3 {{program scope variable must reside in constant address space}} #elif (__OPENCL_C_VERSION__ == 300) #if !defined(__opencl_c_generic_address_space) -// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} #endif #if !defined(__opencl_c_program_scope_global_variables) // expected-error@-9 {{program scope variable must reside in constant address space}} @@ -86,11 +86,11 @@ extern generic float g_generic_extern_var; #if (__OPENCL_C_VERSION__ < 300) -// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} +// expected-error@-2 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} // expected-error@-3 {{extern variable must reside in constant address space}} #elif (__OPENCL_C_VERSION__ == 300) #if !defined(__opencl_c_generic_address_space) -// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} #endif #if !defined(__opencl_c_program_scope_global_variables) // expected-error@-9 {{extern variable must reside in constant address space}} @@ -189,11 +189,11 @@ static generic float l_generic_static_var = 0; #if (__OPENCL_C_VERSION__ < 300) -// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} +// expected-error@-2 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} // expected-error@-3 {{variables in function scope cannot be declared static}} #elif (__OPENCL_C_VERSION__ == 300) #if !defined(__opencl_c_generic_address_space) -// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} #endif #if !defined(__opencl_c_program_scope_global_variables) // expected-error@-9 {{static local variable must reside in constant address space}} @@ -239,11 +239,11 @@ extern generic float l_generic_extern_var; #if (__OPENCL_C_VERSION__ < 300) -// expected-error@-2 {{OpenCL C version 1.2 does not support the 'generic' type qualifier}} +// expected-error@-2 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}} // expected-error@-3 {{extern variable must reside in constant address space}} #elif (__OPENCL_C_VERSION__ == 300) #if !defined(__opencl_c_generic_address_space) -// expected-error@-6 {{OpenCL C version 3.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{type qualifier 'generic' requires OpenCL C 2.0 or later and a feature support}}} #endif #if !defined(__opencl_c_program_scope_global_variables) // expected-error@-9 {{extern variable must reside in constant address space}}