[clang] [clang] Implement constexpr __builtin_bit_cast for complex types (PR #109981)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 16 00:40:28 PDT 2024
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/109981
>From 8a987510829abcba7bdb3572db418f71f33bbd69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 25 Sep 2024 15:45:06 +0200
Subject: [PATCH] [clang] Implement constexpr __builtin_bit_cast for complex
types
Fixes https://github.com/llvm/llvm-project/issues/94620
---
clang/lib/AST/ExprConstant.cpp | 43 +++++++++++++++++++
.../SemaCXX/constexpr-builtin-bit-cast.cpp | 16 +++++++
2 files changed, 59 insertions(+)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 51956c631786b53..4557297e0dd1499 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7237,6 +7237,7 @@ class APValueToBufferConverter {
case APValue::ComplexInt:
case APValue::ComplexFloat:
+ return visitComplex(Val, Ty, Offset);
case APValue::FixedPoint:
// FIXME: We should support these.
@@ -7323,6 +7324,31 @@ class APValueToBufferConverter {
return true;
}
+ bool visitComplex(const APValue &Val, QualType Ty, CharUnits Offset) {
+ const ComplexType *ComplexTy = Ty->castAs<ComplexType>();
+ QualType EltTy = ComplexTy->getElementType();
+ CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
+ bool IsInt = Val.isComplexInt();
+
+ if (IsInt) {
+ if (!visitInt(Val.getComplexIntReal(), EltTy,
+ Offset + (0 * EltSizeChars)))
+ return false;
+ if (!visitInt(Val.getComplexIntImag(), EltTy,
+ Offset + (1 * EltSizeChars)))
+ return false;
+ } else {
+ if (!visitFloat(Val.getComplexFloatReal(), EltTy,
+ Offset + (0 * EltSizeChars)))
+ return false;
+ if (!visitFloat(Val.getComplexFloatImag(), EltTy,
+ Offset + (1 * EltSizeChars)))
+ return false;
+ }
+
+ return true;
+ }
+
bool visitVector(const APValue &Val, QualType Ty, CharUnits Offset) {
const VectorType *VTy = Ty->castAs<VectorType>();
QualType EltTy = VTy->getElementType();
@@ -7595,6 +7621,23 @@ class BufferToAPValueConverter {
return ArrayValue;
}
+ std::optional<APValue> visit(const ComplexType *Ty, CharUnits Offset) {
+ QualType ElementType = Ty->getElementType();
+ CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
+ bool IsInt = ElementType->isIntegerType();
+
+ std::optional<APValue> Values[2];
+ for (unsigned I = 0; I != 2; ++I) {
+ Values[I] = visitType(Ty->getElementType(), Offset + I * ElementWidth);
+ if (!Values[I])
+ return std::nullopt;
+ }
+
+ if (IsInt)
+ return APValue(Values[0]->getInt(), Values[1]->getInt());
+ return APValue(Values[0]->getFloat(), Values[1]->getFloat());
+ }
+
std::optional<APValue> visit(const VectorType *VTy, CharUnits Offset) {
QualType EltTy = VTy->getElementType();
unsigned NElts = VTy->getNumElements();
diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
index 7520b43a194aba6..5ddb77b35ff145e 100644
--- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
+++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
@@ -511,3 +511,19 @@ constexpr bool9 bad_short_to_bool9 = __builtin_bit_cast(bool9, static_cast<unsig
constexpr bool17 bad_int_to_bool17 = __builtin_bit_cast(bool17, 0x0001CAFEU);
}
+
+namespace test_complex {
+ constexpr _Complex unsigned test_int_complex = { 0x0C05FEFE, 0xCAFEBABE };
+ static_assert(round_trip<_Complex unsigned>(0xCAFEBABE0C05FEFEULL), "");
+ static_assert(bit_cast<unsigned long long>(test_int_complex) == (LITTLE_END
+ ? 0xCAFEBABE0C05FEFE
+ : 0x0C05FEFECAFEBABE), "");
+ static_assert(sizeof(double) == 2 * sizeof(float));
+ struct TwoFloats { float A; float B; };
+ constexpr _Complex float test_float_complex = {1.0f, 2.0f};
+ constexpr TwoFloats TF = __builtin_bit_cast(TwoFloats, test_float_complex);
+ static_assert(TF.A == 1.0f && TF.B == 2.0f);
+
+ constexpr double D = __builtin_bit_cast(double, test_float_complex);
+ constexpr int M = __builtin_bit_cast(int, test_int_complex); // expected-error {{__builtin_bit_cast source size does not equal destination size}}
+}
More information about the cfe-commits
mailing list