[clang] [clang] Implement constexpr bit_cast for vectors (PR #66894)

via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 21 23:36:05 PDT 2023


================
@@ -463,3 +463,38 @@ static_assert(bit_cast<long double>(ld539) == fivehundredandthirtynine, "");
 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), "");
+
+typedef bool bool8 __attribute__((ext_vector_type(8)));
+typedef bool bool9 __attribute__((ext_vector_type(9)));
+typedef bool bool17 __attribute__((ext_vector_type(17)));
+typedef bool bool32 __attribute__((ext_vector_type(32)));
+
+static_assert(bit_cast<unsigned char>(bool8{1,0,1,0,1,0,1,0}) == 0x55, "");
+static_assert(round_trip<bool8>(static_cast<unsigned char>(0)), "");
+static_assert(round_trip<bool8>(static_cast<unsigned char>(1)), "");
+static_assert(round_trip<bool8>(static_cast<unsigned char>(0x55)), "");
+
+static_assert(bit_cast<unsigned short>(bool9{1,1,0,1,0,1,0,1,0}) == 0xAB, "");
----------------
DaMatrix wrote:

I don't think it should be: from what I can tell, existing code such as `CodeGenFunction::EmitLoadOfScalar` stores an N-element bool vector directly as a single N-bit integer (with some extra padding bits if the vector length doesn't correspond directly to a native integer type), where the least significant bit corresponds to vector element `0`, etc. To the best of my understanding, this would mean that `bit_cast`-ing a bool vector to an integer type should work the same as `bit_cast`-ing an integer type to another integer type of the same size, and endianness should be irrelevant when casting between integers because both integers are in the native byte order.

It would probably be good to get someone who knows how this stuff is supposed to work to confirm one way or the other, but I'm not sure who that would be.

https://github.com/llvm/llvm-project/pull/66894


More information about the cfe-commits mailing list