[PATCH] D157825: [clang] Implement constexpr bit_cast for vectors
Joey Rabil via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 13 14:03:49 PDT 2023
DaPorkchop_ created this revision.
DaPorkchop_ added a project: clang.
Herald added a project: All.
DaPorkchop_ requested review of this revision.
Herald added a subscriber: cfe-commits.
This makes __builtin_bit_cast support converting to and from vector types in a constexpr context.
Without this patch, attempting to use `std::bit_cast` with a vector type will fail to compile with a message such as:
`constexpr bit_cast involving type '__attribute__((__vector_size__(4 * sizeof(int)))) int const' (vector of 4 'int' values) is not yet supported`
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D157825
Files:
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
Index: clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
===================================================================
--- clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
+++ clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
@@ -463,3 +463,19 @@
static_assert(round_trip<__int128_t>(34.0L));
#endif
}
+
+namespace test_vector {
+
+typedef unsigned uint2 __attribute__((vector_size(2 * sizeof(unsigned))));
+typedef char byte8 __attribute__((vector_size(sizeof(unsigned long long))));
+
+constexpr uint2 test_vector = { 0x0C05FEFE, 0xCAFEBABE };
+
+static_assert(bit_cast<unsigned long long>(test_vector) == (LITTLE_END
+ ? 0xCAFEBABE0C05FEFE
+ : 0x0C05FEFECAFEBABE), "");
+
+static_assert(round_trip<uint2>(0xCAFEBABE0C05FEFEULL), "");
+static_assert(round_trip<byte8>(0xCAFEBABE0C05FEFEULL), "");
+
+}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -6990,10 +6990,11 @@
return visitArray(Val, Ty, Offset);
case APValue::Struct:
return visitRecord(Val, Ty, Offset);
+ case APValue::Vector:
+ return visitVector(Val, Ty, Offset);
case APValue::ComplexInt:
case APValue::ComplexFloat:
- case APValue::Vector:
case APValue::FixedPoint:
// FIXME: We should support these.
@@ -7080,6 +7081,21 @@
return true;
}
+ bool visitVector(const APValue &Val, QualType Ty, CharUnits Offset) {
+ const auto *VT = Ty->castAs<VectorType>();
+
+ CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(VT->getElementType());
+ unsigned VectorLength = Val.getVectorLength();
+ // Visit each of the vector elements
+ for (unsigned I = 0; I != VectorLength; ++I) {
+ const APValue &SubObj = Val.getVectorElt(I);
+ if (!visit(SubObj, VT->getElementType(), Offset + I * ElemWidth))
+ return false;
+ }
+
+ return true;
+ }
+
bool visitInt(const APSInt &Val, QualType Ty, CharUnits Offset) {
APSInt AdjustedVal = Val;
unsigned Width = AdjustedVal.getBitWidth();
@@ -7289,6 +7305,22 @@
return ArrayValue;
}
+ std::optional<APValue> visit(const VectorType *Ty, CharUnits Offset) {
+ size_t NumElements = Ty->getNumElements();
+ CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->getElementType());
+
+ SmallVector<APValue, 4> Elts;
+ for (size_t I = 0; I != NumElements; ++I) {
+ std::optional<APValue> ElementValue =
+ visitType(Ty->getElementType(), Offset + I * ElementWidth);
+ if (!ElementValue)
+ return std::nullopt;
+ Elts.push_back(std::move(*ElementValue));
+ }
+
+ return APValue(Elts.data(), Elts.size());
+ }
+
std::optional<APValue> visit(const Type *Ty, CharUnits Offset) {
return unsupportedType(QualType(Ty, 0));
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157825.549754.patch
Type: text/x-patch
Size: 2965 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230813/0a25fca0/attachment.bin>
More information about the cfe-commits
mailing list