Re: [PATCH] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
rivanvx updated this revision to Diff 64417. rivanvx added a comment. Specifically handle only kernels. https://reviews.llvm.org/D20168 Files: lib/CodeGen/TargetInfo.cpp test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl Index: test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl === --- /dev/null +++ test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl @@ -0,0 +1,65 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s + +// CHECK-NOT: %struct.single_element_struct_arg = type { i32 } +typedef struct single_element_struct_arg +{ +int i; +} single_element_struct_arg_t; + +// CHECK: %struct.struct_arg = type { i32, float, i32 } +typedef struct struct_arg +{ +int i1; +float f; +int i2; +} struct_arg_t; + +// CHECK: %struct.struct_of_arrays_arg = type { [2 x i32], float, [4 x i32], [3 x float], i32 } +typedef struct struct_of_arrays_arg +{ +int i1[2]; +float f1; +int i2[4]; +float f2[3]; +int i3; +} struct_of_arrays_arg_t; + +// CHECK: %struct.struct_of_structs_arg = type { i32, float, %struct.struct_arg, i32 } +typedef struct struct_of_structs_arg +{ +int i1; +float f1; +struct_arg_t s1; +int i2; +} struct_of_structs_arg_t; + +// CHECK-LABEL: @test_single_element_struct_arg +// CHECK: i32 %arg1.coerce +__kernel void test_single_element_struct_arg(single_element_struct_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_arg +// CHECK: %struct.struct_arg %arg1.coerce +__kernel void test_struct_arg(struct_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_of_arrays_arg +// CHECK: %struct.struct_of_arrays_arg %arg1.coerce +__kernel void test_struct_of_arrays_arg(struct_of_arrays_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_of_structs_arg +// CHECK: %struct.struct_of_structs_arg %arg1.coerce +__kernel void test_struct_of_structs_arg(struct_of_structs_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_non_kernel_struct_arg +// CHECK-NOT: %struct.struct_arg %arg1.coerce +void test_non_kernel_struct_arg(struct_arg_t arg1) +{ +} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6825,10 +6825,49 @@ namespace { +class AMDGPUABIInfo final : public DefaultABIInfo { +public: + explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo &FI) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + const unsigned CC = FI.getCallingConvention(); + for (auto &Arg : FI.arguments()) +if (CC == llvm::CallingConv::AMDGPU_KERNEL) + Arg.info = classifyArgumentType(Arg.type); +else + Arg.info = DefaultABIInfo::classifyArgumentType(Arg.type); +} + +/// \brief Classify argument of given type \p Ty. +ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty) const { + llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); + if (!StrTy) { +return DefaultABIInfo::classifyArgumentType(Ty); + } + else if (StrTy->getNumElements() == 1) { +// Coerce single element structs to its element. +return ABIArgInfo::getDirect(); + } + + // If we set CanBeFlattened to true, CodeGen will expand the struct to its + // individual elements, which confuses the Clover OpenCL backend; therefore we + // have to set it to false here. Other args of getDirect() are just defaults. + return ABIArgInfo::getDirect(nullptr, 0, nullptr, false); +} + class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { public: AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; unsigned getOpenCLKernelCallingConv() const override; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
rivanvx updated this revision to Diff 64920. rivanvx marked 2 inline comments as done. https://reviews.llvm.org/D20168 Files: lib/CodeGen/TargetInfo.cpp test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl Index: test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl === --- /dev/null +++ test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl @@ -0,0 +1,66 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s + +// CHECK-NOT: %struct.single_element_struct_arg = type { i32 } +typedef struct single_element_struct_arg +{ +int i; +} single_element_struct_arg_t; + +// CHECK: %struct.struct_arg = type { i32, float, i32 } +typedef struct struct_arg +{ +int i1; +float f; +int i2; +} struct_arg_t; + +// CHECK: %struct.struct_of_arrays_arg = type { [2 x i32], float, [4 x i32], [3 x float], i32 } +typedef struct struct_of_arrays_arg +{ +int i1[2]; +float f1; +int i2[4]; +float f2[3]; +int i3; +} struct_of_arrays_arg_t; + +// CHECK: %struct.struct_of_structs_arg = type { i32, float, %struct.struct_arg, i32 } +typedef struct struct_of_structs_arg +{ +int i1; +float f1; +struct_arg_t s1; +int i2; +} struct_of_structs_arg_t; + +// CHECK-LABEL: @test_single_element_struct_arg +// CHECK: i32 %arg1.coerce +__kernel void test_single_element_struct_arg(single_element_struct_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_arg +// CHECK: %struct.struct_arg %arg1.coerce +__kernel void test_struct_arg(struct_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_of_arrays_arg +// CHECK: %struct.struct_of_arrays_arg %arg1.coerce +__kernel void test_struct_of_arrays_arg(struct_of_arrays_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_of_structs_arg +// CHECK: %struct.struct_of_structs_arg %arg1.coerce +__kernel void test_struct_of_structs_arg(struct_of_structs_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_non_kernel_struct_arg +// CHECK-NOT: %struct.struct_arg %arg1.coerce +// CHECK: %struct.struct_arg* byval +void test_non_kernel_struct_arg(struct_arg_t arg1) +{ +} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6825,10 +6825,50 @@ namespace { +class AMDGPUABIInfo final : public DefaultABIInfo { +public: + explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo &FI) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + unsigned CC = FI.getCallingConvention(); + for (auto &Arg : FI.arguments()) +if (CC == llvm::CallingConv::AMDGPU_KERNEL) + Arg.info = classifyArgumentType(Arg.type); +else + Arg.info = DefaultABIInfo::classifyArgumentType(Arg.type); +} + +/// \brief Classify argument of given type \p Ty. +ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty) const { + llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); + if (!StrTy) { +return DefaultABIInfo::classifyArgumentType(Ty); + } + + // Coerce single element structs to its element. + if (StrTy->getNumElements() == 1) { +return ABIArgInfo::getDirect(); + } + + // If we set CanBeFlattened to true, CodeGen will expand the struct to its + // individual elements, which confuses the Clover OpenCL backend; therefore we + // have to set it to false here. Other args of getDirect() are just defaults. + return ABIArgInfo::getDirect(nullptr, 0, nullptr, false); +} + class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { public: AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; unsigned getOpenCLKernelCallingConv() const override; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
rivanvx added a comment. Addressed both concerns. https://reviews.llvm.org/D20168 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx added inline comments. Comment at: lib/Parse/ParseDecl.cpp:3519 @@ +3518,3 @@ + / 100); +const char *VerSpec = (VerMajor + std::string (".") + VerMinor).c_str(); +Diag(Tok, DiagID) << VerSpec << PrevSpec << isStorageClass; Anastasia wrote: > I think it will be nicer to use string (not char*) here too. Other Spec are const char*, so I did it for consistency. But I don't care either way. http://reviews.llvm.org/D19780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx updated this revision to Diff 56478. rivanvx marked 3 inline comments as done. rivanvx added a comment. I am neither aware how to convert ints to StringRef nor how to concatenate StringRefs. Apologies if I missed something in the API. In any case, this approach looks pretty clean to me. http://reviews.llvm.org/D19780 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Parse/ParseDecl.cpp test/Parser/opencl-cl20.cl test/Parser/opencl-storage-class.cl test/SemaOpenCL/invalid-access-qualifier.cl test/SemaOpenCL/storageclass.cl Index: test/SemaOpenCL/storageclass.cl === --- test/SemaOpenCL/storageclass.cl +++ test/SemaOpenCL/storageclass.cl @@ -13,7 +13,7 @@ constant int L1 = 0; local int L2; - auto int L3 = 7; // expected-error{{OpenCL does not support the 'auto' storage class specifier}} + auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}} global int L4; // expected-error{{function scope variable cannot be declared in global address space}} } Index: test/SemaOpenCL/invalid-access-qualifier.cl === --- test/SemaOpenCL/invalid-access-qualifier.cl +++ test/SemaOpenCL/invalid-access-qualifier.cl @@ -10,5 +10,5 @@ #ifdef CL20 void test4(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'pipe int'}} #else -void test4(__read_write image1d_t i) {} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' earlier than OpenCL2.0 version}} +void test4(__read_write image1d_t i) {} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' earlier than OpenCL version 2.0}} #endif Index: test/Parser/opencl-storage-class.cl === --- test/Parser/opencl-storage-class.cl +++ test/Parser/opencl-storage-class.cl @@ -2,10 +2,10 @@ void test_storage_class_specs() { - static int a;// expected-error {{OpenCL does not support the 'static' storage class specifier}} - register int b; // expected-error {{OpenCL does not support the 'register' storage class specifier}} - extern int c;// expected-error {{OpenCL does not support the 'extern' storage class specifier}} - auto int d; // expected-error {{OpenCL does not support the 'auto' storage class specifier}} + static int a;// expected-error {{OpenCL version 1.0 does not support the 'static' storage class specifier}} + register int b; // expected-error {{OpenCL version 1.0 does not support the 'register' storage class specifier}} + extern int c;// expected-error {{OpenCL version 1.0 does not support the 'extern' storage class specifier}} + auto int d; // expected-error {{OpenCL version 1.0 does not support the 'auto' storage class specifier}} #pragma OPENCL EXTENSION cl_clang_storage_class_specifiers : enable static int e; // expected-error {{static local variable must reside in constant address space}} Index: test/Parser/opencl-cl20.cl === --- test/Parser/opencl-cl20.cl +++ test/Parser/opencl-cl20.cl @@ -10,17 +10,17 @@ return var; } #ifndef CL20 -// expected-error@-5 {{OpenCL does not support the '__generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the '__generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the '__generic' type qualifier}} +// expected-error@-5 {{OpenCL version 1.0 does not support the '__generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the '__generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the '__generic' type qualifier}} #endif generic int * generic_test(generic int *arg) { generic int *var; return var; } #ifndef CL20 -// expected-error@-5 {{OpenCL does not support the 'generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the 'generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the 'generic' type qualifier}} +// expected-error@-5 {{OpenCL version 1.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the 'generic' type qualifier}} #endif Index: lib/Parse/ParseDecl.cpp === --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ScopedPrinter.h" using namespace clang; @@ -3507,9 +3508,13 @@ if (DiagID == diag::ext_duplicate_declspec) Diag(Tok, DiagID) << PrevSpec << FixItHint::CreateRemov
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx added a comment. @Anastasia would you still prefer to make VerSpec a std::string? http://reviews.llvm.org/D19780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx updated this revision to Diff 56479. rivanvx added a comment. Make that int const as well. http://reviews.llvm.org/D19780 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Parse/ParseDecl.cpp test/Parser/opencl-cl20.cl test/Parser/opencl-storage-class.cl test/SemaOpenCL/invalid-access-qualifier.cl test/SemaOpenCL/storageclass.cl Index: test/SemaOpenCL/storageclass.cl === --- test/SemaOpenCL/storageclass.cl +++ test/SemaOpenCL/storageclass.cl @@ -13,7 +13,7 @@ constant int L1 = 0; local int L2; - auto int L3 = 7; // expected-error{{OpenCL does not support the 'auto' storage class specifier}} + auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}} global int L4; // expected-error{{function scope variable cannot be declared in global address space}} } Index: test/SemaOpenCL/invalid-access-qualifier.cl === --- test/SemaOpenCL/invalid-access-qualifier.cl +++ test/SemaOpenCL/invalid-access-qualifier.cl @@ -10,5 +10,5 @@ #ifdef CL20 void test4(read_write pipe int i){} // expected-error{{access qualifier 'read_write' can not be used for 'pipe int'}} #else -void test4(__read_write image1d_t i) {} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' earlier than OpenCL2.0 version}} +void test4(__read_write image1d_t i) {} // expected-error{{access qualifier '__read_write' can not be used for '__read_write image1d_t' earlier than OpenCL version 2.0}} #endif Index: test/Parser/opencl-storage-class.cl === --- test/Parser/opencl-storage-class.cl +++ test/Parser/opencl-storage-class.cl @@ -2,10 +2,10 @@ void test_storage_class_specs() { - static int a;// expected-error {{OpenCL does not support the 'static' storage class specifier}} - register int b; // expected-error {{OpenCL does not support the 'register' storage class specifier}} - extern int c;// expected-error {{OpenCL does not support the 'extern' storage class specifier}} - auto int d; // expected-error {{OpenCL does not support the 'auto' storage class specifier}} + static int a;// expected-error {{OpenCL version 1.0 does not support the 'static' storage class specifier}} + register int b; // expected-error {{OpenCL version 1.0 does not support the 'register' storage class specifier}} + extern int c;// expected-error {{OpenCL version 1.0 does not support the 'extern' storage class specifier}} + auto int d; // expected-error {{OpenCL version 1.0 does not support the 'auto' storage class specifier}} #pragma OPENCL EXTENSION cl_clang_storage_class_specifiers : enable static int e; // expected-error {{static local variable must reside in constant address space}} Index: test/Parser/opencl-cl20.cl === --- test/Parser/opencl-cl20.cl +++ test/Parser/opencl-cl20.cl @@ -10,17 +10,17 @@ return var; } #ifndef CL20 -// expected-error@-5 {{OpenCL does not support the '__generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the '__generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the '__generic' type qualifier}} +// expected-error@-5 {{OpenCL version 1.0 does not support the '__generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the '__generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the '__generic' type qualifier}} #endif generic int * generic_test(generic int *arg) { generic int *var; return var; } #ifndef CL20 -// expected-error@-5 {{OpenCL does not support the 'generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the 'generic' type qualifier}} -// expected-error@-6 {{OpenCL does not support the 'generic' type qualifier}} +// expected-error@-5 {{OpenCL version 1.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the 'generic' type qualifier}} +// expected-error@-6 {{OpenCL version 1.0 does not support the 'generic' type qualifier}} #endif Index: lib/Parse/ParseDecl.cpp === --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ScopedPrinter.h" using namespace clang; @@ -3507,9 +3508,13 @@ if (DiagID == diag::ext_duplicate_declspec) Diag(Tok, DiagID) << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); - else if (DiagID == diag::err_opencl_unknown_type_specifier) -Diag(Tok, DiagID) << PrevSpec << isStorageClass; - else + else if (DiagID == diag::err_ope
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx added a comment. Thanks for the reviews! http://reviews.llvm.org/D19780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx added a comment. Please, can anyone push this? http://reviews.llvm.org/D19780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
rivanvx created this revision. rivanvx added reviewers: arsenm, tstellarAMD. rivanvx added a subscriber: cfe-commits. Herald added a subscriber: kzhuravl. Structs are currently handled as pointer + byval, which makes AMDGPU LLVM backend generate incorrect code when structs are used. This patch changes struct argument to be handled directly and without flattening, which Clover (Mesa 3D Gallium OpenCL state tracker) will be able to handle. Flattening would expand the struct to individual elements and pass each as a separate argument, which Clover can not handle. Furthermore, such expansion does not fit the OpenCL programming model which requires to explicitely specify each argument index, size and memory location. This patch is a modification of a patch provided by Matt Arsenault. http://reviews.llvm.org/D20168 Files: lib/CodeGen/TargetInfo.cpp Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6808,10 +6808,41 @@ namespace { +class AMDGPUABIInfo final : public DefaultABIInfo { +public: + explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo &FI) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto &Arg : FI.arguments()) +Arg.info = classifyArgumentType(Arg.type); +} + +/// \brief Classify argument of given type \p Ty. +ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty) const { + llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); + if (!StrTy) { +return DefaultABIInfo::classifyArgumentType(Ty); + } + + // If we set CanBeFlattened to true, CodeGen will expand the struct to its + // individual elements, which confuses the Clover OpenCL backend; therefore we + // have to set it to false here. Other args of getDirect() are just defaults. + return ABIArgInfo::getDirect(nullptr, 0, nullptr, false); +} + class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { public: AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; }; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6808,10 +6808,41 @@ namespace { +class AMDGPUABIInfo final : public DefaultABIInfo { +public: + explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo &FI) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto &Arg : FI.arguments()) +Arg.info = classifyArgumentType(Arg.type); +} + +/// \brief Classify argument of given type \p Ty. +ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty) const { + llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); + if (!StrTy) { +return DefaultABIInfo::classifyArgumentType(Ty); + } + + // If we set CanBeFlattened to true, CodeGen will expand the struct to its + // individual elements, which confuses the Clover OpenCL backend; therefore we + // have to set it to false here. Other args of getDirect() are just defaults. + return ABIArgInfo::getDirect(nullptr, 0, nullptr, false); +} + class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { public: AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx added a comment. Could we solve that at a later point? There is one more place where such code is already used, but this would enlarge the scope of this patch. If yes, I am wiling to factor it out after this is merged. http://reviews.llvm.org/D19780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
rivanvx updated this revision to Diff 57023. rivanvx added a comment. Now with 100% more tests. http://reviews.llvm.org/D20168 Files: lib/CodeGen/TargetInfo.cpp test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl Index: test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl === --- /dev/null +++ test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl @@ -0,0 +1,16 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s + +// CHECK: %struct.struct_arg = type { i32, float, i32 } +typedef struct struct_arg +{ +int i1; +float f; +int i2; +} struct_arg_t; + +// CHECK-LABEL: @test_struct_arg +// CHECK: %struct.struct_arg %arg1.coerce +kernel void test_struct_arg(struct_arg_t arg1) +{ +} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6808,10 +6808,41 @@ namespace { +class AMDGPUABIInfo final : public DefaultABIInfo { +public: + explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo &FI) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto &Arg : FI.arguments()) +Arg.info = classifyArgumentType(Arg.type); +} + +/// \brief Classify argument of given type \p Ty. +ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty) const { + llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); + if (!StrTy) { +return DefaultABIInfo::classifyArgumentType(Ty); + } + + // If we set CanBeFlattened to true, CodeGen will expand the struct to its + // individual elements, which confuses the Clover OpenCL backend; therefore we + // have to set it to false here. Other args of getDirect() are just defaults. + return ABIArgInfo::getDirect(nullptr, 0, nullptr, false); +} + class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { public: AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; }; Index: test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl === --- /dev/null +++ test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl @@ -0,0 +1,16 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s + +// CHECK: %struct.struct_arg = type { i32, float, i32 } +typedef struct struct_arg +{ +int i1; +float f; +int i2; +} struct_arg_t; + +// CHECK-LABEL: @test_struct_arg +// CHECK: %struct.struct_arg %arg1.coerce +kernel void test_struct_arg(struct_arg_t arg1) +{ +} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6808,10 +6808,41 @@ namespace { +class AMDGPUABIInfo final : public DefaultABIInfo { +public: + explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo &FI) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto &Arg : FI.arguments()) +Arg.info = classifyArgumentType(Arg.type); +} + +/// \brief Classify argument of given type \p Ty. +ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty) const { + llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); + if (!StrTy) { +return DefaultABIInfo::classifyArgumentType(Ty); + } + + // If we set CanBeFlattened to true, CodeGen will expand the struct to its + // individual elements, which confuses the Clover OpenCL backend; therefore we + // have to set it to false here. Other args of getDirect() are just defaults. + return ABIArgInfo::getDirect(nullptr, 0, nullptr, false); +} + class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { public: AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19780: Output OpenCL version in Clang diagnostics
rivanvx added a comment. @Anastasia I looked into introducing a separate getOpenCLVersion() function (or perhaps three - major version, minor version and version string). This would have to be used in lib/CodeGen/TargetInfo.cpp and lib/Parse/ParseDecl.cpp, and I am undecided on where should one put this code. One option would be in Parse/Parser.h inside class Parser, and then TargetInfo.cpp would have to include Parser.h, unless we decide to declare it inside AST/ASTContext.h. In any case, this has so far two usages, and they are different (major and minor version in TargetInfo.cpp vs version string in ParseDecl.cpp). Therefore, I would propose to leave this as is for now, and rethink it after the same code has to be used in more places. http://reviews.llvm.org/D19780 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
rivanvx updated this revision to Diff 58920. rivanvx added a comment. Updated patch. Single element structs are coerced to its element, and there are tests for structs of different sizes, structs of arrays, structs containing structs. Arrays of structs are disallowed by clang in kernels. Non-kernel functions are not specifically handled, should they be? How to decide? http://reviews.llvm.org/D20168 Files: lib/CodeGen/TargetInfo.cpp test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl Index: test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl === --- /dev/null +++ test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl @@ -0,0 +1,59 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s + +// CHECK-NOT: %struct.single_element_struct_arg = type { i32 } +typedef struct single_element_struct_arg +{ +int i; +} single_element_struct_arg_t; + +// CHECK: %struct.struct_arg = type { i32, float, i32 } +typedef struct struct_arg +{ +int i1; +float f; +int i2; +} struct_arg_t; + +// CHECK: %struct.struct_of_arrays_arg = type { [2 x i32], float, [4 x i32], [3 x float], i32 } +typedef struct struct_of_arrays_arg +{ +int i1[2]; +float f1; +int i2[4]; +float f2[3]; +int i3; +} struct_of_arrays_arg_t; + +// CHECK: %struct.struct_of_structs_arg = type { i32, float, %struct.struct_arg, i32 } +typedef struct struct_of_structs_arg +{ +int i1; +float f1; +struct_arg_t s1; +int i2; +} struct_of_structs_arg_t; + +// CHECK-LABEL: @test_single_element_struct_arg +// CHECK: i32 %arg1.coerce +kernel void test_single_element_struct_arg(single_element_struct_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_arg +// CHECK: %struct.struct_arg %arg1.coerce +kernel void test_struct_arg(struct_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_of_arrays_arg +// CHECK: %struct.struct_of_arrays_arg %arg1.coerce +kernel void test_struct_of_arrays_arg(struct_of_arrays_arg_t arg1) +{ +} + +// CHECK-LABEL: @test_struct_of_structs_arg +// CHECK: %struct.struct_of_structs_arg %arg1.coerce +kernel void test_struct_of_structs_arg(struct_of_structs_arg_t arg1) +{ +} Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6808,10 +6808,45 @@ namespace { +class AMDGPUABIInfo final : public DefaultABIInfo { +public: + explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo &FI) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto &Arg : FI.arguments()) +Arg.info = classifyArgumentType(Arg.type); +} + +/// \brief Classify argument of given type \p Ty. +ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty) const { + llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); + if (!StrTy) { +return DefaultABIInfo::classifyArgumentType(Ty); + } + else if (StrTy->getNumElements() == 1) { +// Coerce single element structs to its element. +return ABIArgInfo::getDirect(); + } + + // If we set CanBeFlattened to true, CodeGen will expand the struct to its + // individual elements, which confuses the Clover OpenCL backend; therefore we + // have to set it to false here. Other args of getDirect() are just defaults. + return ABIArgInfo::getDirect(nullptr, 0, nullptr, false); +} + class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo { public: AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const override; }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits