[clang] [Clang] Make matrix type trivially copyable (PR #193634)

via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 27 18:53:36 PDT 2026


https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/193634

>From c42f8bf52b9a890ee09a9b86191cdae3248af4dd Mon Sep 17 00:00:00 2001
From: Joao Saffran <jderezende at microsoft.com>
Date: Wed, 22 Apr 2026 10:04:39 -0700
Subject: [PATCH 01/10] sync

---
 clang/lib/Headers/hlsl/hlsl_detail.h         |  9 +++++++++
 clang/lib/Headers/hlsl/hlsl_intrinsics.h     |  5 +++++
 clang/test/CodeGenHLSL/builtins/asfloat.hlsl | 20 +++++++++++++++++++-
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index c691d85283de4..e8f73d8d025e7 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -30,6 +30,15 @@ template <typename T> struct enable_if<true, T> {
 template <bool B, class T = void>
 using enable_if_t = typename enable_if<B, T>::Type;
 
+template <typename U, typename T, int C, int R>
+constexpr enable_if_t<sizeof(U) == sizeof(T), matrix<U, C, R>>
+bit_cast(matrix<T, C, R> V) {
+  matrix<U, C, R> Result;
+  for (int i = 0; i < C * R; ++i)
+    Result[i / R][i % R] = __builtin_bit_cast(U, V[i / R][i % R]);
+  return Result;
+}
+
 template <typename U, typename T, int N>
 constexpr enable_if_t<sizeof(U) == sizeof(T), vector<U, N>>
 bit_cast(vector<T, N> V) {
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index cced7b0eabb1f..3f38b084f3779 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -24,6 +24,11 @@ namespace hlsl {
 /// \brief Interprets the bit pattern of x as float point number.
 /// \param Val The input value.
 
+template <typename T, int C, int R>
+constexpr matrix<float, C, R> asfloat(matrix<T, C, R> V) {
+  return __detail::bit_cast<float, T, C, R>(V);
+}
+
 template <typename T, int N>
 constexpr vector<float, N> asfloat(vector<T, N> V) {
   return __detail::bit_cast<float, T, N>(V);
diff --git a/clang/test/CodeGenHLSL/builtins/asfloat.hlsl b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
index 72802e8ef09be..bf569fbc83e5b 100644
--- a/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
@@ -21,7 +21,6 @@ float test_float(float p0) {
 
 // CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} 
 // CHECK: bitcast <4 x i32> [[VAL]] to <4 x float>
-
 float4 test_vector_uint(uint4 p0) {
   return asfloat(p0);
 }
@@ -38,3 +37,22 @@ float4 test_vector_int(int4 p0) {
 float4 test_vector_float(float4 p0) {
   return asfloat(p0);
 }
+
+// CHECK: define {{.*}}test_matrix_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} 
+// CHECK: bitcast <4 x i32> [[VAL]] to <4 x float>
+float4x4 test_matrix_uint(uint4x4 p0) {
+  return asfloat(p0);
+}
+
+// CHECK: define {{.*}}test_matrix_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} 
+// CHECK: bitcast <4 x i32> [[VAL]] to <4 x float>
+float4x4 test_matrix_int(int4x4 p0) {
+  return asfloat(p0);
+}
+
+// CHECK: define {{.*}}test_matrix_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}} 
+// CHECK-NOT: bitcast
+// CHECK: ret <4 x float> [[VAL]]
+float4x4 test_matrix_float(float4x4 p0) {
+  return asfloat(p0);
+}
\ No newline at end of file

>From 7177ce7451362166b85d5e5f63fe1d7ca56a5126 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 16:48:30 -0700
Subject: [PATCH 02/10] mark matrix as easly copyable

---
 clang/include/clang/AST/ASTContext.h         |  2 ++
 clang/include/clang/AST/TypeBase.h           | 12 ++++++++++++
 clang/lib/AST/ASTContext.cpp                 | 15 +++++++++++++++
 clang/lib/AST/Type.cpp                       |  5 +++++
 clang/lib/Headers/hlsl/hlsl_detail.h         |  9 ---------
 clang/test/CodeGenHLSL/builtins/asfloat.hlsl | 19 -------------------
 6 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 902b32cd4d987..663457702ed8b 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -3175,6 +3175,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// actually be an array type).
   QualType getBaseElementType(QualType QT) const;
 
+  QualType getMatrixBaseElementType(QualType QT) const;
+
   /// Return number of constant array elements.
   uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
 
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index a64bbb99b13d2..b4d57c2f48ad3 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -3011,6 +3011,8 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
   /// qualifiers from the outermost type.
   const ArrayType *getAsArrayTypeUnsafe() const;
 
+  const MatrixType *getAsMatrixTypeUnsafe() const;
+
   /// Member-template castAs<specific type>.  Look through sugar for
   /// the underlying instance of \<specific type>.
   ///
@@ -9325,6 +9327,16 @@ inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
   return cast<ArrayType>(getUnqualifiedDesugaredType());
 }
 
+inline const MatrixType *Type::getAsMatrixTypeUnsafe() const {
+  if (const auto *matrix = dyn_cast<MatrixType>(this))
+    return matrix;
+
+  if (!isa<MatrixType>(CanonicalType))
+    return nullptr;
+
+  return cast<MatrixType>(getUnqualifiedDesugaredType());
+}
+
 template <typename T> const T *Type::castAs() const {
   static_assert(!TypeIsArrayType<T>::value,
                 "ArrayType cannot be used with castAs!");
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 5588b1829eb52..bdd113ac7e329 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -8123,6 +8123,21 @@ QualType ASTContext::getBaseElementType(QualType type) const {
   return getQualifiedType(type, qs);
 }
 
+QualType ASTContext::getMatrixBaseElementType(QualType type) const {
+  Qualifiers qs;
+  while (true) {
+    SplitQualType split = type.getSplitDesugaredType();
+    const MatrixType *matrix = split.Ty->getAsMatrixTypeUnsafe();
+    if (!matrix)
+      break;
+
+    type = matrix->getElementType();
+    qs.addConsistentQualifiers(split.Quals);
+  }
+
+  return getQualifiedType(type, qs);
+}
+
 /// getConstantArrayElementCount - Returns number of constant array elements.
 uint64_t
 ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA)  const {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 1cc318697d936..22bd53c0f6730 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2867,6 +2867,11 @@ static bool isTriviallyCopyableTypeImpl(const QualType &type,
     return isTriviallyCopyableTypeImpl(Context.getBaseElementType(type),
                                        Context, IsCopyConstructible);
 
+  // if(type->isMatrixType())
+  //   return
+  //   isTriviallyCopyableTypeImpl(Context.getMatrixBaseElementType(type),
+  //                                      Context, IsCopyConstructible);
+
   if (type.hasNonTrivialObjCLifetime())
     return false;
 
diff --git a/clang/lib/Headers/hlsl/hlsl_detail.h b/clang/lib/Headers/hlsl/hlsl_detail.h
index e8f73d8d025e7..c691d85283de4 100644
--- a/clang/lib/Headers/hlsl/hlsl_detail.h
+++ b/clang/lib/Headers/hlsl/hlsl_detail.h
@@ -30,15 +30,6 @@ template <typename T> struct enable_if<true, T> {
 template <bool B, class T = void>
 using enable_if_t = typename enable_if<B, T>::Type;
 
-template <typename U, typename T, int C, int R>
-constexpr enable_if_t<sizeof(U) == sizeof(T), matrix<U, C, R>>
-bit_cast(matrix<T, C, R> V) {
-  matrix<U, C, R> Result;
-  for (int i = 0; i < C * R; ++i)
-    Result[i / R][i % R] = __builtin_bit_cast(U, V[i / R][i % R]);
-  return Result;
-}
-
 template <typename U, typename T, int N>
 constexpr enable_if_t<sizeof(U) == sizeof(T), vector<U, N>>
 bit_cast(vector<T, N> V) {
diff --git a/clang/test/CodeGenHLSL/builtins/asfloat.hlsl b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
index bf569fbc83e5b..78a3141f75af1 100644
--- a/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
@@ -37,22 +37,3 @@ float4 test_vector_int(int4 p0) {
 float4 test_vector_float(float4 p0) {
   return asfloat(p0);
 }
-
-// CHECK: define {{.*}}test_matrix_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} 
-// CHECK: bitcast <4 x i32> [[VAL]] to <4 x float>
-float4x4 test_matrix_uint(uint4x4 p0) {
-  return asfloat(p0);
-}
-
-// CHECK: define {{.*}}test_matrix_int{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} 
-// CHECK: bitcast <4 x i32> [[VAL]] to <4 x float>
-float4x4 test_matrix_int(int4x4 p0) {
-  return asfloat(p0);
-}
-
-// CHECK: define {{.*}}test_matrix_float{{.*}}(<4 x float> {{.*}} [[VAL:%.*]]){{.*}} 
-// CHECK-NOT: bitcast
-// CHECK: ret <4 x float> [[VAL]]
-float4x4 test_matrix_float(float4x4 p0) {
-  return asfloat(p0);
-}
\ No newline at end of file

>From 3ee7f99145bbed95bdfbad5adece3ba2e843597c Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 17:05:59 -0700
Subject: [PATCH 03/10] fix tests

---
 clang/lib/AST/Type.cpp                 | 7 +++----
 clang/test/CodeGenHLSL/BoolMatrix.hlsl | 8 ++------
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 22bd53c0f6730..0d5d0c2b675bc 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2867,10 +2867,9 @@ static bool isTriviallyCopyableTypeImpl(const QualType &type,
     return isTriviallyCopyableTypeImpl(Context.getBaseElementType(type),
                                        Context, IsCopyConstructible);
 
-  // if(type->isMatrixType())
-  //   return
-  //   isTriviallyCopyableTypeImpl(Context.getMatrixBaseElementType(type),
-  //                                      Context, IsCopyConstructible);
+  if (type->isMatrixType())
+    return isTriviallyCopyableTypeImpl(Context.getMatrixBaseElementType(type),
+                                       Context, IsCopyConstructible);
 
   if (type.hasNonTrivialObjCLifetime())
     return false;
diff --git a/clang/test/CodeGenHLSL/BoolMatrix.hlsl b/clang/test/CodeGenHLSL/BoolMatrix.hlsl
index e9841ae6c9a90..90669fa58888e 100644
--- a/clang/test/CodeGenHLSL/BoolMatrix.hlsl
+++ b/clang/test/CodeGenHLSL/BoolMatrix.hlsl
@@ -75,9 +75,7 @@ bool fn3() {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[RETVAL:%.*]] = alloca i1, align 4
 // CHECK-NEXT:    [[ARR:%.*]] = alloca [2 x [2 x <2 x i32>]], align 4
-// CHECK-NEXT:    store <4 x i32> splat (i32 1), ptr [[ARR]], align 4
-// CHECK-NEXT:    [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [2 x <2 x i32>], ptr [[ARR]], i32 1
-// CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr [[ARRAYINIT_ELEMENT]], align 4
+// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[ARR]], ptr align 4 @constinit, i32 32, i1 false)
 // CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [2 x <2 x i32>]], ptr [[ARR]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr [[ARRAYIDX]], align 4
 // CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <4 x i32> [[TMP0]], i32 1
@@ -129,9 +127,7 @@ void fn6() {
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
 // CHECK-NEXT:    [[ARR:%.*]] = alloca [2 x [2 x <2 x i32>]], align 4
-// CHECK-NEXT:    store <4 x i32> splat (i32 1), ptr [[ARR]], align 4
-// CHECK-NEXT:    [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [2 x <2 x i32>], ptr [[ARR]], i32 1
-// CHECK-NEXT:    store <4 x i32> zeroinitializer, ptr [[ARRAYINIT_ELEMENT]], align 4
+// CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[ARR]], ptr align 4 @constinit.1, i32 32, i1 false)
 // CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [2 x <2 x i32>]], ptr [[ARR]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP0:%.*]] = getelementptr <4 x i32>, ptr [[ARRAYIDX]], i32 0, i32 1
 // CHECK-NEXT:    store i32 0, ptr [[TMP0]], align 4

>From a74c02c9d88b5effb094146643be0a02af69b9a4 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 17:07:29 -0700
Subject: [PATCH 04/10] clean up

---
 clang/lib/Headers/hlsl/hlsl_intrinsics.h     | 5 -----
 clang/test/CodeGenHLSL/builtins/asfloat.hlsl | 1 +
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 3f38b084f3779..cced7b0eabb1f 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -24,11 +24,6 @@ namespace hlsl {
 /// \brief Interprets the bit pattern of x as float point number.
 /// \param Val The input value.
 
-template <typename T, int C, int R>
-constexpr matrix<float, C, R> asfloat(matrix<T, C, R> V) {
-  return __detail::bit_cast<float, T, C, R>(V);
-}
-
 template <typename T, int N>
 constexpr vector<float, N> asfloat(vector<T, N> V) {
   return __detail::bit_cast<float, T, N>(V);
diff --git a/clang/test/CodeGenHLSL/builtins/asfloat.hlsl b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
index 78a3141f75af1..72802e8ef09be 100644
--- a/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/asfloat.hlsl
@@ -21,6 +21,7 @@ float test_float(float p0) {
 
 // CHECK: define {{.*}}test_vector_uint{{.*}}(<4 x i32> {{.*}} [[VAL:%.*]]){{.*}} 
 // CHECK: bitcast <4 x i32> [[VAL]] to <4 x float>
+
 float4 test_vector_uint(uint4 p0) {
   return asfloat(p0);
 }

>From e65bba16d7e8e07c4c5d1005312f7d514a6b74cf Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 17:26:06 -0700
Subject: [PATCH 05/10] adding test

---
 clang/test/SemaCXX/type-traits.cpp | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 65c0729571f99..adca277b4e60b 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted -Wno-c++17-extensions  %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted -Wno-c++17-extensions  %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++17 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted  %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++20 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted -fenable-matrix -Wno-c++17-extensions  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted -fenable-matrix -Wno-c++17-extensions  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++17 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted -fenable-matrix  %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++20 -fblocks -Wno-deprecated-builtins -Wno-defaulted-function-deleted -fenable-matrix  %s
 
 
 struct NonPOD { NonPOD(int); };
@@ -45,6 +45,10 @@ struct HasAnonymousUnion {
 typedef int Vector __attribute__((vector_size(16)));
 typedef int VectorExt __attribute__((ext_vector_type(4)));
 
+typedef float __attribute__((matrix_type(2, 3))) fm2x3;
+typedef int   __attribute__((matrix_type(4, 4))) im4x4;
+
+
 using ComplexFloat = _Complex float;
 using ComplexInt = _Complex int;
 
@@ -1359,6 +1363,8 @@ void is_trivially_copyable2()
   static_assert(__is_trivially_copyable(NonTrivialStruct));
   static_assert(__is_trivially_copyable(AllDefaulted));
   static_assert(__is_trivially_copyable(AllDeleted));
+  static_assert(__is_trivially_copyable(fm2x3));
+  static_assert(__is_trivially_copyable(im4x4));
 
   static_assert(!__is_trivially_copyable(void));
   static_assert(!__is_trivially_copyable(SuperNonTrivialStruct));
@@ -1374,6 +1380,7 @@ void is_trivially_copyable2()
   static_assert(!__is_trivially_copyable(AnIncompleteType[1])); // expected-error {{incomplete type}}
   static_assert(!__is_trivially_copyable(void));
   static_assert(!__is_trivially_copyable(const volatile void));
+
 }
 
 struct CStruct {
@@ -1426,6 +1433,7 @@ void is_standard_layout()
   static_assert(__is_standard_layout(CppStructStandardAr));
   static_assert(__is_standard_layout(Vector));
   static_assert(__is_standard_layout(VectorExt));
+  static_assert(__is_standard_layout(VectorExt));
 
   typedef CppStructNonStandardByBase CppStructNonStandardByBaseAr[4];
 
@@ -2906,7 +2914,9 @@ void is_trivial()
   static_assert(__is_trivial(DerivesHasProt));
   static_assert(__is_trivial(Vector));
   static_assert(__is_trivial(VectorExt));
-
+  
+  
+  static_assert(!__is_trivial(fm2x3));
   static_assert(!__is_trivial(HasCons));
   static_assert(!__is_trivial(HasCopyAssign));
   static_assert(!__is_trivial(HasMoveAssign));

>From 914f0d66a8a098feb0f18ef480cd8bb3766adbb5 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 17:32:00 -0700
Subject: [PATCH 06/10] remove unrelated test

---
 clang/test/SemaCXX/type-traits.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index adca277b4e60b..252e1632c1287 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -2915,8 +2915,6 @@ void is_trivial()
   static_assert(__is_trivial(Vector));
   static_assert(__is_trivial(VectorExt));
   
-  
-  static_assert(!__is_trivial(fm2x3));
   static_assert(!__is_trivial(HasCons));
   static_assert(!__is_trivial(HasCopyAssign));
   static_assert(!__is_trivial(HasMoveAssign));

>From 467b53f6906deb581521caa84dc0b4ba411fd8c4 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 17:33:08 -0700
Subject: [PATCH 07/10] clean up

---
 clang/test/SemaCXX/type-traits.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 252e1632c1287..400caacd54c4e 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -1433,7 +1433,6 @@ void is_standard_layout()
   static_assert(__is_standard_layout(CppStructStandardAr));
   static_assert(__is_standard_layout(Vector));
   static_assert(__is_standard_layout(VectorExt));
-  static_assert(__is_standard_layout(VectorExt));
 
   typedef CppStructNonStandardByBase CppStructNonStandardByBaseAr[4];
 
@@ -2914,7 +2913,7 @@ void is_trivial()
   static_assert(__is_trivial(DerivesHasProt));
   static_assert(__is_trivial(Vector));
   static_assert(__is_trivial(VectorExt));
-  
+
   static_assert(!__is_trivial(HasCons));
   static_assert(!__is_trivial(HasCopyAssign));
   static_assert(!__is_trivial(HasMoveAssign));

>From 86936237943f4f00eba54c2018a6d67be9636a67 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 17:33:41 -0700
Subject: [PATCH 08/10] clean up

---
 clang/test/SemaCXX/type-traits.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 400caacd54c4e..0691eadbb20c8 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -1380,7 +1380,6 @@ void is_trivially_copyable2()
   static_assert(!__is_trivially_copyable(AnIncompleteType[1])); // expected-error {{incomplete type}}
   static_assert(!__is_trivially_copyable(void));
   static_assert(!__is_trivially_copyable(const volatile void));
-
 }
 
 struct CStruct {

>From 0dec37ba6f84a4f375cb93695bf095943ea32dea Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 22 Apr 2026 17:34:35 -0700
Subject: [PATCH 09/10] clean up

---
 clang/test/SemaCXX/type-traits.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 0691eadbb20c8..8decb1f61395e 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -47,8 +47,6 @@ typedef int VectorExt __attribute__((ext_vector_type(4)));
 
 typedef float __attribute__((matrix_type(2, 3))) fm2x3;
 typedef int   __attribute__((matrix_type(4, 4))) im4x4;
-
-
 using ComplexFloat = _Complex float;
 using ComplexInt = _Complex int;
 

>From 0f3d34624824d3c9f03f9ce1a55baf0469b4b323 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 27 Apr 2026 18:53:19 -0700
Subject: [PATCH 10/10] remove complexity

---
 clang/include/clang/AST/ASTContext.h |  2 --
 clang/include/clang/AST/TypeBase.h   | 12 ------------
 clang/lib/AST/ASTContext.cpp         | 15 ---------------
 clang/lib/AST/Type.cpp               | 11 +++++++----
 4 files changed, 7 insertions(+), 33 deletions(-)

diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 663457702ed8b..902b32cd4d987 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -3175,8 +3175,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
   /// actually be an array type).
   QualType getBaseElementType(QualType QT) const;
 
-  QualType getMatrixBaseElementType(QualType QT) const;
-
   /// Return number of constant array elements.
   uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
 
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index b4d57c2f48ad3..a64bbb99b13d2 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -3011,8 +3011,6 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
   /// qualifiers from the outermost type.
   const ArrayType *getAsArrayTypeUnsafe() const;
 
-  const MatrixType *getAsMatrixTypeUnsafe() const;
-
   /// Member-template castAs<specific type>.  Look through sugar for
   /// the underlying instance of \<specific type>.
   ///
@@ -9327,16 +9325,6 @@ inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
   return cast<ArrayType>(getUnqualifiedDesugaredType());
 }
 
-inline const MatrixType *Type::getAsMatrixTypeUnsafe() const {
-  if (const auto *matrix = dyn_cast<MatrixType>(this))
-    return matrix;
-
-  if (!isa<MatrixType>(CanonicalType))
-    return nullptr;
-
-  return cast<MatrixType>(getUnqualifiedDesugaredType());
-}
-
 template <typename T> const T *Type::castAs() const {
   static_assert(!TypeIsArrayType<T>::value,
                 "ArrayType cannot be used with castAs!");
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index bdd113ac7e329..5588b1829eb52 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -8123,21 +8123,6 @@ QualType ASTContext::getBaseElementType(QualType type) const {
   return getQualifiedType(type, qs);
 }
 
-QualType ASTContext::getMatrixBaseElementType(QualType type) const {
-  Qualifiers qs;
-  while (true) {
-    SplitQualType split = type.getSplitDesugaredType();
-    const MatrixType *matrix = split.Ty->getAsMatrixTypeUnsafe();
-    if (!matrix)
-      break;
-
-    type = matrix->getElementType();
-    qs.addConsistentQualifiers(split.Quals);
-  }
-
-  return getQualifiedType(type, qs);
-}
-
 /// getConstantArrayElementCount - Returns number of constant array elements.
 uint64_t
 ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA)  const {
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 0d5d0c2b675bc..7030feb8b72de 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2867,10 +2867,6 @@ static bool isTriviallyCopyableTypeImpl(const QualType &type,
     return isTriviallyCopyableTypeImpl(Context.getBaseElementType(type),
                                        Context, IsCopyConstructible);
 
-  if (type->isMatrixType())
-    return isTriviallyCopyableTypeImpl(Context.getMatrixBaseElementType(type),
-                                       Context, IsCopyConstructible);
-
   if (type.hasNonTrivialObjCLifetime())
     return false;
 
@@ -2880,6 +2876,13 @@ static bool isTriviallyCopyableTypeImpl(const QualType &type,
   //   called trivially copy constructible types.
 
   QualType CanonicalType = type.getCanonicalType();
+
+  if (CanonicalType->isMatrixType()) {
+    const auto *MatrixTy = CanonicalType->getAs<MatrixType>();
+    return isTriviallyCopyableTypeImpl(MatrixTy->getElementType(), Context,
+                                       IsCopyConstructible);
+  }
+
   if (CanonicalType->isDependentType())
     return false;
 



More information about the cfe-commits mailing list