[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