Re: [PATCH] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
arsenm closed this revision. arsenm added a comment. r279463 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] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
arsenm accepted this revision. arsenm added a comment. This revision is now accepted and ready to land. LGTM 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] 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] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
arsenm added inline comments. Comment at: lib/CodeGen/TargetInfo.cpp:6856 @@ +6855,3 @@ + } + else if (StrTy->getNumElements() == 1) { +// Coerce single element structs to its element. No else after return Comment at: test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl:62 @@ +61,3 @@ +// CHECK-LABEL: @test_non_kernel_struct_arg +// CHECK-NOT: %struct.struct_arg %arg1.coerce +void test_non_kernel_struct_arg(struct_arg_t arg1) Positive checks are greatly preferred 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] 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 ) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo ) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo ) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + const unsigned CC = FI.getCallingConvention(); + for (auto : 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 ) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule ) 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 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 ) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo ) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo ) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto : 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 ) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule ) 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
arsenm added a comment. Also some tests for non-kernel functions. We might want to keep this as byval for calling those http://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] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
arsenm added a comment. Some larger and smaller structs too. I think it would be good if single element structs are replaced with the element type http://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] D20168: [CodeGen] Handle structs directly in AMDGPUABIInfo
arsenm added a comment. Can you add some tests that include arrays, struct within structs and arrays of structs? http://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] 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 ) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo ) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo ) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto : 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 ) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule ) 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 ) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo ) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo ) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto : 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 ) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule ) 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
arsenm added a comment. Needs tests http://reviews.llvm.org/D20168 ___ 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 ) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo ) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo ) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto : 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 ) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule ) 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 ) : DefaultABIInfo(CGT) {} + +private: + ABIArgInfo classifyArgumentType(QualType Ty) const; + + void computeInfo(CGFunctionInfo ) const override; +}; + +void AMDGPUABIInfo::computeInfo(CGFunctionInfo ) const { + if (!getCXXABI().classifyReturnType(FI)) +FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + + for (auto : 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 ) -: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} +: TargetCodeGenInfo(new AMDGPUABIInfo(CGT)) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule ) const override; }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits