https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/98629
>From ba498f559c742e62c13a09cb0b909d57d986e19e Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com> Date: Fri, 12 Jul 2024 06:13:51 -0700 Subject: [PATCH 1/2] [clang] Limit alignment for emitted vectors The max aligment that ISel and therefore LLVM Verifier accepts is 2^14. The patch also forces indirect passing and returning of vectors bigger than this limit for generic and x86_64 targets. --- clang/include/clang/Basic/TargetInfo.h | 3 +++ clang/lib/AST/ASTContext.cpp | 2 ++ clang/lib/Basic/TargetInfo.cpp | 2 ++ clang/lib/CodeGen/ABIInfoImpl.cpp | 8 ++++++++ clang/lib/CodeGen/Targets/X86.cpp | 4 ++++ clang/test/CodeGen/big-vectors.c | 17 +++++++++++++++++ 6 files changed, 36 insertions(+) create mode 100644 clang/test/CodeGen/big-vectors.c diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index a58fb5f979272..5f4e5c50bf7df 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -133,6 +133,7 @@ struct TransferrableTargetInfo { unsigned short SuitableAlign; unsigned short NewAlign; unsigned MaxVectorAlign; + unsigned MaxPossibleAlign; unsigned MaxTLSAlign; const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat, @@ -848,6 +849,8 @@ class TargetInfo : public TransferrableTargetInfo, /// Return the maximum vector alignment supported for the given target. unsigned getMaxVectorAlign() const { return MaxVectorAlign; } + unsigned getMaxPossibleAlign() const { return MaxPossibleAlign; } + unsigned getMaxOpenCLWorkGroupSize() const { return MaxOpenCLWorkGroupSize; } /// Return the alignment (in bits) of the thrown exception object. This is diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 497579dcc56b6..303322a7f0032 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1985,6 +1985,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { VT->getVectorKind() == VectorKind::RVVFixedLengthMask) // Adjust the alignment for fixed-length RVV vectors. Align = std::min<unsigned>(64, Width); + else if (Target->getMaxPossibleAlign() < Align) + Align = Target->getMaxPossibleAlign(); break; } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 29f5cd14e46e1..5874df93d712b 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -121,6 +121,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; MaxVectorAlign = 0; + // LLVM can only process alignment up to 2^14 bytes. + MaxPossibleAlign = 8 << 14; MaxTLSAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index e9a26abb77837..2b469d999438e 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -38,6 +38,10 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { : Context.LongLongTy)) return getNaturalAlignIndirect(Ty); + if (Ty->getAs<VectorType>() && + Context.getTypeSize(Ty) > getTarget().getMaxPossibleAlign()) + return getNaturalAlignIndirect(Ty); + return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); } @@ -60,6 +64,10 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { : getContext().LongLongTy)) return getNaturalAlignIndirect(RetTy); + if (RetTy->getAs<VectorType>() && + getContext().getTypeSize(RetTy) > getTarget().getMaxPossibleAlign()) + return getNaturalAlignIndirect(RetTy); + return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) : ABIArgInfo::getDirect()); } diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 1dc3172a6bdf9..de6f7580475fd 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -2175,6 +2175,10 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { if (Ty->isBitIntType()) return getNaturalAlignIndirect(Ty); + if (Ty->getAs<VectorType>() && + getContext().getTypeSize(Ty) > getTarget().getMaxPossibleAlign()) + return getNaturalAlignIndirect(Ty); + return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) : ABIArgInfo::getDirect()); } diff --git a/clang/test/CodeGen/big-vectors.c b/clang/test/CodeGen/big-vectors.c new file mode 100644 index 0000000000000..dc44ca07ab8b0 --- /dev/null +++ b/clang/test/CodeGen/big-vectors.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -O0 -triple x86_64 %s -emit-llvm -o - | FileCheck --check-prefixes=x86 %s +// RUN: %clang_cc1 -O0 -triple spir64 %s -emit-llvm -o - | FileCheck --check-prefixes=SPIR %s + +typedef float fvec __attribute__((ext_vector_type(5120))); +fvec foo(fvec a) { + fvec c; + return c; +} +// x86-DAG: define{{.*}}@foo{{.*}}sret(<5120 x float>) align 16384{{.*}}byval(<5120 x float>) align 16384 +// SPIR: define{{.*}}@foo({{.*}}sret(<5120 x float>) align 16384{{.*}}byval(<5120 x float>) align 16384 + +void bar() { + fvec a; + fvec c = foo(a); +// x86-DAG: call void @foo({{.*}}sret(<5120 x float>) align 16384{{.*}}byval(<5120 x float>) align 16384 +// SPIR: call spir_func void @foo({{.*}}sret(<5120 x float>) align 16384{{.*}}byval(<5120 x float>) align 16384 +} >From 2aa206b51f3d14bcc18eec42dd6d9e3341d601c7 Mon Sep 17 00:00:00 2001 From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com> Date: Tue, 16 Jul 2024 08:04:42 -0700 Subject: [PATCH 2/2] Use MaxVectorAlign --- clang/include/clang/Basic/TargetInfo.h | 3 --- clang/lib/AST/ASTContext.cpp | 2 -- clang/lib/Basic/TargetInfo.cpp | 3 +-- clang/lib/CodeGen/ABIInfoImpl.cpp | 4 ++-- clang/lib/CodeGen/Targets/X86.cpp | 2 +- clang/test/CodeGen/X86/x86-vec-i128.c | 6 +++--- 6 files changed, 7 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 5f4e5c50bf7df..a58fb5f979272 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -133,7 +133,6 @@ struct TransferrableTargetInfo { unsigned short SuitableAlign; unsigned short NewAlign; unsigned MaxVectorAlign; - unsigned MaxPossibleAlign; unsigned MaxTLSAlign; const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat, @@ -849,8 +848,6 @@ class TargetInfo : public TransferrableTargetInfo, /// Return the maximum vector alignment supported for the given target. unsigned getMaxVectorAlign() const { return MaxVectorAlign; } - unsigned getMaxPossibleAlign() const { return MaxPossibleAlign; } - unsigned getMaxOpenCLWorkGroupSize() const { return MaxOpenCLWorkGroupSize; } /// Return the alignment (in bits) of the thrown exception object. This is diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 303322a7f0032..497579dcc56b6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1985,8 +1985,6 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { VT->getVectorKind() == VectorKind::RVVFixedLengthMask) // Adjust the alignment for fixed-length RVV vectors. Align = std::min<unsigned>(64, Width); - else if (Target->getMaxPossibleAlign() < Align) - Align = Target->getMaxPossibleAlign(); break; } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 5874df93d712b..c35ddab447c2d 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -120,9 +120,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { LargeArrayMinWidth = 0; LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; - MaxVectorAlign = 0; // LLVM can only process alignment up to 2^14 bytes. - MaxPossibleAlign = 8 << 14; + MaxVectorAlign = 8 << 14; MaxTLSAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 2b469d999438e..2df1fcbeb722e 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -39,7 +39,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { return getNaturalAlignIndirect(Ty); if (Ty->getAs<VectorType>() && - Context.getTypeSize(Ty) > getTarget().getMaxPossibleAlign()) + Context.getTypeSize(Ty) > getTarget().getMaxVectorAlign()) return getNaturalAlignIndirect(Ty); return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) @@ -65,7 +65,7 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { return getNaturalAlignIndirect(RetTy); if (RetTy->getAs<VectorType>() && - getContext().getTypeSize(RetTy) > getTarget().getMaxPossibleAlign()) + getContext().getTypeSize(RetTy) > getTarget().getMaxVectorAlign()) return getNaturalAlignIndirect(RetTy); return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index de6f7580475fd..a94052e36ecc4 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -2176,7 +2176,7 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { return getNaturalAlignIndirect(Ty); if (Ty->getAs<VectorType>() && - getContext().getTypeSize(Ty) > getTarget().getMaxPossibleAlign()) + getContext().getTypeSize(Ty) > getTarget().getMaxVectorAlign()) return getNaturalAlignIndirect(Ty); return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) diff --git a/clang/test/CodeGen/X86/x86-vec-i128.c b/clang/test/CodeGen/X86/x86-vec-i128.c index ee58cb92da6b1..039459ee06d2b 100644 --- a/clang/test/CodeGen/X86/x86-vec-i128.c +++ b/clang/test/CodeGen/X86/x86-vec-i128.c @@ -32,7 +32,7 @@ typedef unsigned long long v32u64 __attribute__((vector_size(32))); typedef unsigned __int128 v32u128 __attribute__((vector_size(32))); v32u64 test_v32u128(v32u64 a, v32u128 b) { -// MEM256ALIGN16: define{{.*}} <4 x i64> @test_v32u128(ptr noundef byval(<4 x i64>) align 16 %{{.*}}, ptr noundef byval(<2 x i128>) align 16 %{{.*}}) +// MEM256ALIGN16: define{{.*}} void @test_v32u128(ptr dead_on_unwind noalias writable sret(<4 x i64>) align 16 %{{.*}}, ptr noundef byval(<4 x i64>) align 16 %{{.*}}, ptr noundef byval(<2 x i128>) align 16 %{{.*}}) // MEM256ALIGN32: define{{.*}} <4 x i64> @test_v32u128(ptr noundef byval(<4 x i64>) align 32 %{{.*}}, ptr noundef byval(<2 x i128>) align 32 %{{.*}}) // CLANG10ABI256: define{{.*}} <4 x i64> @test_v32u128(<4 x i64> noundef %{{.*}}, ptr noundef byval(<2 x i128>) align 32 %{{.*}}) // CLANG9ABI256: define{{.*}} <4 x i64> @test_v32u128(<4 x i64> noundef %{{.*}}, <2 x i128> noundef %{{.*}}) @@ -43,8 +43,8 @@ typedef unsigned long long v64u64 __attribute__((vector_size(64))); typedef unsigned __int128 v64u128 __attribute__((vector_size(64))); v64u64 test_v64u128(v64u64 a, v64u128 b) { -// MEM512ALIGN16: define{{.*}} <8 x i64> @test_v64u128(ptr noundef byval(<8 x i64>) align 16 %{{.*}}, ptr noundef byval(<4 x i128>) align 16 %{{.*}}) -// MEM512ALIGN32: define{{.*}} <8 x i64> @test_v64u128(ptr noundef byval(<8 x i64>) align 32 %{{.*}}, ptr noundef byval(<4 x i128>) align 32 %{{.*}}) +// MEM512ALIGN16: define{{.*}} void @test_v64u128(ptr dead_on_unwind noalias writable sret(<8 x i64>) align 16 %{{.*}}, ptr noundef byval(<8 x i64>) align 16 %{{.*}}, ptr noundef byval(<4 x i128>) align 16 %{{.*}}) +// MEM512ALIGN32: define{{.*}} void @test_v64u128(ptr dead_on_unwind noalias writable sret(<8 x i64>) align 32 %{{.*}}, ptr noundef byval(<8 x i64>) align 32 %{{.*}}, ptr noundef byval(<4 x i128>) align 32 %{{.*}}) // MEM512ALIGN64: define{{.*}} <8 x i64> @test_v64u128(ptr noundef byval(<8 x i64>) align 64 %{{.*}}, ptr noundef byval(<4 x i128>) align 64 %{{.*}}) // CLANG10ABI512: define{{.*}} <8 x i64> @test_v64u128(<8 x i64> noundef %{{.*}}, ptr noundef byval(<4 x i128>) align 64 %{{.*}}) // CLANG9ABI512: define{{.*}} <8 x i64> @test_v64u128(<8 x i64> noundef %{{.*}}, <4 x i128> noundef %{{.*}}) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits