[clang] [clang] Limit alignment for emitted vectors (PR #98629)

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 16 08:05:18 PDT 2024


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.podchishchaeva at 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.podchishchaeva at 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 %{{.*}})



More information about the cfe-commits mailing list