Author: Victor Campos Date: 2026-09-21T09:55:54+01:00 New Revision: 462f83ce4fff5d7fef0e6beb6b8bb2e568a5d13f
URL: https://github.com/llvm/llvm-project/commit/462f83ce4fff5d7fef0e6beb6b8bb2e568a5d13f DIFF: https://github.com/llvm/llvm-project/commit/462f83ce4fff5d7fef0e6beb6b8bb2e568a5d13f.diff LOG: [Clang] Fix padding clearing logic for packed boolean vectors in big endian (#224033) The memory layout of packed boolean vectors in big endian mode is quite involved. This patch adds support for determining the occupied bits of this type in big endian mode, so that the correct bits are cleared as padding. Added: Modified: clang/lib/AST/ASTContext.cpp clang/test/CodeGen/builtin-clear-padding-codegen.c clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index ee8663e6906af..e74423ca8c8a1 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -15999,12 +15999,13 @@ struct PaddingCalculator { } void VisitVector(const clang::VectorType *VT, uint64_t StartBitOffset) { - uint64_t SizeBit = [&]() -> uint64_t { - if (VT->isPackedVectorBoolType(Ctx)) - return VT->getNumElements(); - return getScalarOccupiedSizeInBits(VT->getElementType()) * - VT->getNumElements(); - }(); + if (VT->isPackedVectorBoolType(Ctx)) { + VisitPackedBooleanVector(VT, StartBitOffset); + return; + } + + uint64_t SizeBit = getScalarOccupiedSizeInBits(VT->getElementType()) * + VT->getNumElements(); OccuppiedIntervals.push_back( ASTContext::BitInterval{StartBitOffset, StartBitOffset + SizeBit}); } @@ -16050,6 +16051,42 @@ struct PaddingCalculator { StartBitOffset + StorageSizeInBits}); } + void VisitPackedBooleanVector(const VectorType *VTy, + uint64_t StartBitOffset) { + const uint64_t CharWidth = Ctx.getCharWidth(); + assert(StartBitOffset % CharWidth == 0 && + "Expected aligned packed boolean vector"); + assert(VTy->isPackedVectorBoolType(Ctx)); + const uint64_t OccupiedSizeInBits = VTy->getNumElements(); + + if (Ctx.getTargetInfo().isLittleEndian()) { + OccuppiedIntervals.push_back( + {StartBitOffset, StartBitOffset + OccupiedSizeInBits}); + return; + } + + // Only the sequence of bytes containing occupied bits has its order + // reversed, but the bits within each byte are still counted from the least + // significant bit. So if there are fully padding bytes, they reside at the + // higher addresses in both endiannesses. + const uint64_t NumFullyOccupiedBytes = OccupiedSizeInBits / CharWidth; + const uint64_t NumRemainingOccupiedBits = OccupiedSizeInBits % CharWidth; + + uint64_t Start = StartBitOffset; + // Partially occupied byte at the beginning + if (NumRemainingOccupiedBits > 0) { + const uint64_t ByteEnd = Start + CharWidth; + OccuppiedIntervals.push_back({Start, Start + NumRemainingOccupiedBits}); + Start = ByteEnd; + } + + // The remaining fully occupied bytes form a contiguous interval + if (NumFullyOccupiedBytes > 0) { + OccuppiedIntervals.push_back( + {Start, Start + NumFullyOccupiedBytes * CharWidth}); + } + } + void MergeOccuppiedIntervals() { std::sort(OccuppiedIntervals.begin(), OccuppiedIntervals.end(), [](const ASTContext::BitInterval &lhs, diff --git a/clang/test/CodeGen/builtin-clear-padding-codegen.c b/clang/test/CodeGen/builtin-clear-padding-codegen.c index 317b86e6014c4..6d1d98bd4b5bf 100644 --- a/clang/test/CodeGen/builtin-clear-padding-codegen.c +++ b/clang/test/CodeGen/builtin-clear-padding-codegen.c @@ -3356,3 +3356,187 @@ struct BitfieldUnnamedOnly { void testBitfieldUnnamedOnly(struct BitfieldUnnamedOnly *s) { __builtin_clear_padding(s); } + +typedef _Bool bool6 __attribute__((ext_vector_type(6))); + +// CHECK64-LABEL: define dso_local void @testPackedBooleanVectorLessThan8Elements( +// CHECK64-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-NEXT: [[ENTRY:.*:]] +// CHECK64-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// CHECK64-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// CHECK64-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 +// CHECK64-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// CHECK64-NEXT: ret void +// +// ARM-LABEL: define dso_local void @testPackedBooleanVectorLessThan8Elements( +// ARM-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-NEXT: [[ENTRY:.*:]] +// ARM-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// ARM-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// ARM-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 +// ARM-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// ARM-NEXT: ret void +// +void testPackedBooleanVectorLessThan8Elements(bool6 *v) { + __builtin_clear_padding(v); +} + +typedef _Bool bool8 __attribute__((ext_vector_type(8))); + +// CHECK64-LABEL: define dso_local void @testPackedBooleanVector8Elements( +// CHECK64-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-NEXT: [[ENTRY:.*:]] +// CHECK64-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: ret void +// +// ARM-LABEL: define dso_local void @testPackedBooleanVector8Elements( +// ARM-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-NEXT: [[ENTRY:.*:]] +// ARM-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-NEXT: ret void +// +void testPackedBooleanVector8Elements(bool8 *v) { + __builtin_clear_padding(v); +} + +typedef _Bool bool12 __attribute__((ext_vector_type(12))); + +// CHECK64-LE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// CHECK64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-LE-NEXT: [[ENTRY:.*:]] +// CHECK64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// CHECK64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// CHECK64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// CHECK64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// CHECK64-LE-NEXT: ret void +// +// ARM-LE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-LE-NEXT: [[ENTRY:.*:]] +// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// ARM-LE-NEXT: ret void +// +// ARM-BE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-BE-NEXT: [[ENTRY:.*:]] +// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2 +// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2 +// ARM-BE-NEXT: ret void +// +// AARCH64-BE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// AARCH64-BE-NEXT: [[ENTRY:.*:]] +// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2 +// AARCH64-BE-NEXT: ret void +// +void testPackedBooleanVectorMoreThan8Elements(bool12 *v) { + __builtin_clear_padding(v); +} + +typedef _Bool bool33 __attribute__((ext_vector_type(33))); + +// CHECK64-LE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// CHECK64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-LE-NEXT: [[ENTRY:.*:]] +// CHECK64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4 +// CHECK64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 +// CHECK64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// CHECK64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 +// CHECK64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// CHECK64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// CHECK64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// CHECK64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// CHECK64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// CHECK64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// CHECK64-LE-NEXT: ret void +// +// ARM-LE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-LE-NEXT: [[ENTRY:.*:]] +// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4 +// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 +// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 +// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// ARM-LE-NEXT: ret void +// +// ARM-BE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-BE-NEXT: [[ENTRY:.*:]] +// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 8 +// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 8 +// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// ARM-BE-NEXT: ret void +// +// AARCH64-BE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// AARCH64-BE-NEXT: [[ENTRY:.*:]] +// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 8 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 8 +// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// AARCH64-BE-NEXT: ret void +// +void testPackedBooleanVectorWithFullyPaddingBytes(bool33 *v) { + __builtin_clear_padding(v); +} diff --git a/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp b/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp index 55651e21b3a40..7de1b0bb59fc5 100644 --- a/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp +++ b/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp @@ -4650,6 +4650,190 @@ extern "C" void testBitfieldUnnamedOnly(struct BitfieldUnnamedOnly *s) { __builtin_clear_padding(s); } +typedef bool bool6 __attribute__((ext_vector_type(6))); + +// CHECK64-LABEL: define dso_local void @testPackedBooleanVectorLessThan8Elements( +// CHECK64-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-NEXT: [[ENTRY:.*:]] +// CHECK64-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// CHECK64-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// CHECK64-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 +// CHECK64-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// CHECK64-NEXT: ret void +// +// ARM-LABEL: define dso_local void @testPackedBooleanVectorLessThan8Elements( +// ARM-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-NEXT: [[ENTRY:.*:]] +// ARM-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// ARM-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// ARM-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 +// ARM-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// ARM-NEXT: ret void +// +extern "C" void testPackedBooleanVectorLessThan8Elements(bool6 *v) { + __builtin_clear_padding(v); +} + +typedef bool bool8 __attribute__((ext_vector_type(8))); + +// CHECK64-LABEL: define dso_local void @testPackedBooleanVector8Elements( +// CHECK64-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-NEXT: [[ENTRY:.*:]] +// CHECK64-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-NEXT: ret void +// +// ARM-LABEL: define dso_local void @testPackedBooleanVector8Elements( +// ARM-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-NEXT: [[ENTRY:.*:]] +// ARM-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-NEXT: ret void +// +extern "C" void testPackedBooleanVector8Elements(bool8 *v) { + __builtin_clear_padding(v); +} + +typedef bool bool12 __attribute__((ext_vector_type(12))); + +// CHECK64-LE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// CHECK64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-LE-NEXT: [[ENTRY:.*:]] +// CHECK64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// CHECK64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// CHECK64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// CHECK64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// CHECK64-LE-NEXT: ret void +// +// ARM-LE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-LE-NEXT: [[ENTRY:.*:]] +// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1 +// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 1 +// ARM-LE-NEXT: ret void +// +// ARM-BE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-BE-NEXT: [[ENTRY:.*:]] +// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2 +// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2 +// ARM-BE-NEXT: ret void +// +// AARCH64-BE-LABEL: define dso_local void @testPackedBooleanVectorMoreThan8Elements( +// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// AARCH64-BE-NEXT: [[ENTRY:.*:]] +// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 2 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 15 +// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 2 +// AARCH64-BE-NEXT: ret void +// +extern "C" void testPackedBooleanVectorMoreThan8Elements(bool12 *v) { + __builtin_clear_padding(v); +} + +typedef bool bool33 __attribute__((ext_vector_type(33))); + +// CHECK64-LE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// CHECK64-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK64-LE-NEXT: [[ENTRY:.*:]] +// CHECK64-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// CHECK64-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// CHECK64-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4 +// CHECK64-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 +// CHECK64-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// CHECK64-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 +// CHECK64-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// CHECK64-LE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// CHECK64-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// CHECK64-LE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// CHECK64-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// CHECK64-LE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// CHECK64-LE-NEXT: ret void +// +// ARM-LE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// ARM-LE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-LE-NEXT: [[ENTRY:.*:]] +// ARM-LE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-LE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-LE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 4 +// ARM-LE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 +// ARM-LE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// ARM-LE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 +// ARM-LE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// ARM-LE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// ARM-LE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// ARM-LE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// ARM-LE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// ARM-LE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// ARM-LE-NEXT: ret void +// +// ARM-BE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// ARM-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// ARM-BE-NEXT: [[ENTRY:.*:]] +// ARM-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 4 +// ARM-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 4 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 8 +// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 8 +// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// ARM-BE-NEXT: ret void +// +// AARCH64-BE-LABEL: define dso_local void @testPackedBooleanVectorWithFullyPaddingBytes( +// AARCH64-BE-SAME: ptr noundef [[V:%.*]]) #[[ATTR0]] { +// AARCH64-BE-NEXT: [[ENTRY:.*:]] +// AARCH64-BE-NEXT: [[V_ADDR:%.*]] = alloca ptr, align 8 +// AARCH64-BE-NEXT: store ptr [[V]], ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[V_ADDR]], align 8 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 8 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 +// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 8 +// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 5 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 1 +// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 6 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 2 +// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 7 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 1 +// AARCH64-BE-NEXT: ret void +// +extern "C" void testPackedBooleanVectorWithFullyPaddingBytes(bool33 *v) { + __builtin_clear_padding(v); +} + #ifndef _WIN32 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wbitfield-width" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
