https://github.com/xiongzile updated https://github.com/llvm/llvm-project/pull/225494
>From aa4b747ea45d05e37ec6f8d30b3f0dd1821c7d39 Mon Sep 17 00:00:00 2001 From: Elio <[email protected]> Date: Wed, 23 Sep 2026 03:10:13 +0800 Subject: [PATCH 1/3] [Clang][CodeGen] Fix oversized bit-field placement on big-endian CodeGen treated the full declared width of an oversized bit-field as value bits. On big-endian targets that stored the value at the low end of the storage unit, so `unsigned char value : 16` initialized to 0xAB landed in memory as 00 AB and was loaded from the second byte. Clamp the value width to the declared type before the big-endian offset adjustment, matching CGBitFieldInfo::MakeInfo. --- clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 5 ++ .../aarch64-be-oversized-bitfield.cpp | 47 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 clang/test/CodeGenCXX/aarch64-be-oversized-bitfield.cpp diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index d98d7c0c96dc3d..56199dc18b7943 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -243,6 +243,11 @@ void CGRecordLowering::setBitFieldInfo( Info.StorageOffset = StartOffset; if (Info.Size > Info.StorageSize) Info.Size = Info.StorageSize; + // CGBitFieldInfo::MakeInfo does the same clamp + llvm::Type *FieldType = Types.ConvertTypeForMem(FD->getType()); + unsigned FieldTypeSize = DataLayout.getTypeAllocSizeInBits(FieldType); + if (Info.Size > FieldTypeSize) + Info.Size = FieldTypeSize; // Reverse the bit offsets for big endian machines. Because we represent // a bitfield as a single large integer load, we can imagine the bits // counting from the most-significant-bit instead of the diff --git a/clang/test/CodeGenCXX/aarch64-be-oversized-bitfield.cpp b/clang/test/CodeGenCXX/aarch64-be-oversized-bitfield.cpp new file mode 100644 index 00000000000000..8dc72c55f984dd --- /dev/null +++ b/clang/test/CodeGenCXX/aarch64-be-oversized-bitfield.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -std=c++17 -emit-llvm -O0 \ +// RUN: -fdump-record-layouts-simple -o %t.be.ll %s | FileCheck %s --check-prefix=LAYOUT-BE +// RUN: FileCheck %s --check-prefix=BE <%t.be.ll +// RUN: %clang_cc1 -triple aarch64-linux-gnu -std=c++17 -emit-llvm -O0 \ +// RUN: -fdump-record-layouts-simple -o %t.le.ll %s | FileCheck %s --check-prefix=LAYOUT-LE +// RUN: FileCheck %s --check-prefix=LE <%t.le.ll + +// An oversized bit-field has a declared width larger than its type. Only the +// type width is a value; the rest is padding, and the value bits come first. +// On AArch64 big endian that places 0xAB in the high byte of the 16-bit +// container (memory AB 00). A load therefore shifts the container right by 8. +// Little endian keeps the value in the low byte (memory AB 00 as well, as the +// integer 0x00AB). + +#pragma clang diagnostic ignored "-Wbitfield-width" + +struct S { + unsigned char value : 16; +}; + +// LAYOUT-BE: BitFields:[ +// LAYOUT-BE-NEXT: <CGBitFieldInfo Offset:8 Size:8 IsSigned:0 StorageSize:16 StorageOffset:0 +// LAYOUT-BE-NEXT: ]> +// LAYOUT-LE: BitFields:[ +// LAYOUT-LE-NEXT: <CGBitFieldInfo Offset:0 Size:8 IsSigned:0 StorageSize:16 StorageOffset:0 +// LAYOUT-LE-NEXT: ]> + +// First byte is 0xAB. The padding byte is not the value. +// BE: @global = global { i8, i8 } { i8 -85, i8 undef }, align 2 +// LE: @global = global { i8, i8 } { i8 -85, i8 undef }, align 2 +extern "C" S global = {0xAB}; + +// BE-LABEL: define {{.*}} @get( +// BE: [[P:%.*]] = load ptr, ptr %p.addr +// BE: [[LOAD:%.*]] = load i16, ptr [[P]] +// BE-NEXT: [[SHL:%.*]] = lshr i16 [[LOAD]], 8 +// BE-NEXT: trunc i16 [[SHL]] to i8 +// +// LE-LABEL: define {{.*}} @get( +// LE: [[P:%.*]] = load ptr, ptr %p.addr +// LE: [[LOAD:%.*]] = load i16, ptr [[P]] +// LE-NOT: lshr +// LE: [[CLEAR:%.*]] = and i16 [[LOAD]], 255 +// LE-NEXT: trunc i16 [[CLEAR]] to i8 +extern "C" unsigned char get(const S *p) { + return p->value; +} >From 7c0868223ac0cdb79ee75007c2b13f0977ace40f Mon Sep 17 00:00:00 2001 From: Elio <[email protected]> Date: Wed, 23 Sep 2026 03:10:14 +0800 Subject: [PATCH 2/3] [Clang] Adjust padding calculation for corrected oversized bit-fields __builtin_clear_padding located occupied bits using the old big-endian layout, which placed padding before the value of an oversized bit-field. After the CodeGen fix, value bits come first. Size the value container to the field type and keep only the low-order occupied bits inside it, so clear_padding no longer zeroes the value. --- clang/lib/AST/ASTContext.cpp | 27 +- .../builtin-clear-padding-codegen.cpp | 395 ++++++------------ 2 files changed, 152 insertions(+), 270 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index e74423ca8c8a1b..f2d7ebcbd3c5ed 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -15917,13 +15917,15 @@ struct PaddingCalculator { const uint64_t DeclaredSizeInBits = Field->getBitWidthValue(); - // Handle over-sized bitfields: - // unsigned char a : 12; - // In this case, DeclaredSizeInBits is 12, but the actually occupied bit - // size is 8, while the remaining 4 bits are padding. - const uint64_t OccupiedSizeInBits = - std::min(DeclaredSizeInBits, - static_cast<uint64_t>(Ctx.getIntWidth(Field->getType()))); + // Oversized bit-fields (declared width larger than the field type) keep + // only the type's width as the value container. The extra declared bits + // are padding and follow that container (Itanium C++ ABI 2.4). + // getIntWidth may be narrower still (bool, _BitInt); those occupied bits + // are the low-order bits of the value container. + const uint64_t ValueFieldBits = + std::min(DeclaredSizeInBits, Ctx.getTypeSize(Field->getType())); + const uint64_t OccupiedSizeInBits = std::min( + ValueFieldBits, static_cast<uint64_t>(Ctx.getIntWidth(Field->getType()))); if (Ctx.getTargetInfo().isLittleEndian()) { OccuppiedIntervals.push_back( @@ -15941,14 +15943,11 @@ struct PaddingCalculator { // the partially occupied bytes in either end, if present, their bit // intervals need to be adjusted so that they count from the MSB instead. // - // FIXME: For over-sized bitfields in BE, Clang allocates padding bits - // before the occupied bits. This violates the ABI rules, which say that - // padding should be allocated after, regardless of endianness (Itanium C++ - // ABI ยง2.4, II.1(b)). The current code accommodates for Clang's current - // behaviour though, and bumps Start forward to skip the leading padding - // bits. + // Within the value container, occupied bits are its low-order bits, which + // are allocated last. Padding from an oversized declared width follows + // the container. const uint64_t Start = - StartBitOffset + DeclaredSizeInBits - OccupiedSizeInBits; + StartBitOffset + ValueFieldBits - OccupiedSizeInBits; const uint64_t End = Start + OccupiedSizeInBits; const uint64_t CharWidth = Ctx.getCharWidth(); diff --git a/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp b/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp index 7de1b0bb59fc5f..599a8ba03c30df 100644 --- a/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp +++ b/clang/test/CodeGenCXX/builtin-clear-padding-codegen.cpp @@ -1782,32 +1782,20 @@ struct OversizedBitfield { // ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4 // ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4 // ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4 -// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // ARM-BE-NEXT: ret void // // AARCH64-BE-LABEL: define dso_local void @testOversizedBitfield( @@ -1816,32 +1804,20 @@ struct OversizedBitfield { // AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8 // AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8 // AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8 -// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // AARCH64-BE-NEXT: ret void // extern "C" void testOversizedBitfield(struct OversizedBitfield *s) { @@ -1898,32 +1874,20 @@ extern "C" void testOversizedBitfield(struct OversizedBitfield *s) { // ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4 // ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4 // ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4 -// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // ARM-BE-NEXT: ret void // // AARCH64-BE-LABEL: define dso_local void @testOversizedBitfieldVolatileStruct( @@ -1932,32 +1896,20 @@ extern "C" void testOversizedBitfield(struct OversizedBitfield *s) { // AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8 // AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8 // AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8 -// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // AARCH64-BE-NEXT: ret void // extern "C" void testOversizedBitfieldVolatileStruct( @@ -2021,32 +1973,20 @@ struct VolatileOversizedBitfield { // ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4 // ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4 // ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4 -// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // ARM-BE-NEXT: ret void // // AARCH64-BE-LABEL: define dso_local void @testVolatileOversizedBitfield( @@ -2055,32 +1995,20 @@ struct VolatileOversizedBitfield { // AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8 // AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8 // AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8 -// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // AARCH64-BE-NEXT: ret void // extern "C" void testVolatileOversizedBitfield( @@ -2138,32 +2066,20 @@ extern "C" void testVolatileOversizedBitfield( // ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4 // ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4 // ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4 -// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// ARM-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// ARM-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// ARM-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// ARM-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// ARM-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// ARM-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// ARM-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// ARM-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// ARM-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// ARM-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// ARM-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// ARM-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// ARM-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// ARM-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// ARM-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// ARM-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// ARM-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// ARM-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// ARM-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// ARM-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // ARM-BE-NEXT: ret void // // AARCH64-BE-LABEL: define dso_local void @testVolatileOversizedBitfieldVolatileStruct( @@ -2172,32 +2088,20 @@ extern "C" void testVolatileOversizedBitfield( // AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8 // AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8 // AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8 -// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// AARCH64-BE-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 63 -// AARCH64-BE-NEXT: store i8 [[TMP3]], ptr [[TMP1]], align 4 -// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], -64 -// AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 1 -// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 2 -// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 -// AARCH64-BE-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[TMP0]], i32 8 -// AARCH64-BE-NEXT: [[TMP10:%.*]] = load i8, ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP11:%.*]] = and i8 [[TMP10]], 31 -// AARCH64-BE-NEXT: store i8 [[TMP11]], ptr [[TMP9]], align 4 -// AARCH64-BE-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 -// AARCH64-BE-NEXT: [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP14:%.*]] = and i8 [[TMP13]], -32 -// AARCH64-BE-NEXT: store i8 [[TMP14]], ptr [[TMP12]], align 4 -// AARCH64-BE-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP15]], align 1 -// AARCH64-BE-NEXT: [[TMP16:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP16]], align 2 -// AARCH64-BE-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP17]], align 1 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +// AARCH64-BE-NEXT: [[TMP4:%.*]] = getelementptr i8, ptr [[TMP0]], i32 12 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP4]], align 4 +// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 13 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP5]], align 1 +// AARCH64-BE-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[TMP0]], i32 14 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP6]], align 2 +// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 15 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP7]], align 1 // AARCH64-BE-NEXT: ret void // extern "C" void testVolatileOversizedBitfieldVolatileStruct( @@ -4838,8 +4742,8 @@ extern "C" void testPackedBooleanVectorWithFullyPaddingBytes(bool33 *v) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wbitfield-width" -// Match Clang's existing oversized-field representation. On big endian the -// occupied byte is byte 1, so clearing padding must leave that byte intact. +// Value bits occupy the first byte on both endians. The second byte is +// padding and must be cleared. struct BitfieldOversizedAligned { unsigned char value : 16; }; @@ -4870,8 +4774,8 @@ struct BitfieldOversizedAligned { // ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4 // ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4 // ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4 -// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 // ARM-BE-NEXT: ret void // // AARCH64-BE-LABEL: define dso_local void @testBitfieldOversizedAligned( @@ -4880,16 +4784,15 @@ struct BitfieldOversizedAligned { // AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8 // AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8 // AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8 -// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 // AARCH64-BE-NEXT: ret void // extern "C" void testBitfieldOversizedAligned(BitfieldOversizedAligned *s) { __builtin_clear_padding(s); } -// The occupied bits cross a byte boundary after more than one byte of leading -// padding on big endian. The declared width also exceeds the allocation type. +// Eight value bits occupy the first byte. The rest of the allocation is padding. struct BitfieldOversizedBeyondBoundary { unsigned char value : 17; }; @@ -4928,18 +4831,12 @@ struct BitfieldOversizedBeyondBoundary { // ARM-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 4 // ARM-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 4 // ARM-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 4 -// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 2 -// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// ARM-BE-NEXT: [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 1 -// ARM-BE-NEXT: [[TMP4:%.*]] = and i8 [[TMP3]], 127 -// ARM-BE-NEXT: store i8 [[TMP4]], ptr [[TMP2]], align 1 -// ARM-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// ARM-BE-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 2 -// ARM-BE-NEXT: [[TMP7:%.*]] = and i8 [[TMP6]], -128 -// ARM-BE-NEXT: store i8 [[TMP7]], ptr [[TMP5]], align 2 -// ARM-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// ARM-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 +// ARM-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// ARM-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// ARM-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// ARM-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// ARM-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// ARM-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 // ARM-BE-NEXT: ret void // // AARCH64-BE-LABEL: define dso_local void @testBitfieldOversizedBeyondBoundary( @@ -4948,18 +4845,12 @@ struct BitfieldOversizedBeyondBoundary { // AARCH64-BE-NEXT: [[S_ADDR:%.*]] = alloca ptr, align 8 // AARCH64-BE-NEXT: store ptr [[S]], ptr [[S_ADDR]], align 8 // AARCH64-BE-NEXT: [[TMP0:%.*]] = load ptr, ptr [[S_ADDR]], align 8 -// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 0 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 2 -// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// AARCH64-BE-NEXT: [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 1 -// AARCH64-BE-NEXT: [[TMP4:%.*]] = and i8 [[TMP3]], 127 -// AARCH64-BE-NEXT: store i8 [[TMP4]], ptr [[TMP2]], align 1 -// AARCH64-BE-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// AARCH64-BE-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 2 -// AARCH64-BE-NEXT: [[TMP7:%.*]] = and i8 [[TMP6]], -128 -// AARCH64-BE-NEXT: store i8 [[TMP7]], ptr [[TMP5]], align 2 -// AARCH64-BE-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 -// AARCH64-BE-NEXT: store i8 0, ptr [[TMP8]], align 1 +// AARCH64-BE-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +// AARCH64-BE-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP2]], align 2 +// AARCH64-BE-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[TMP0]], i32 3 +// AARCH64-BE-NEXT: store i8 0, ptr [[TMP3]], align 1 // AARCH64-BE-NEXT: ret void // extern "C" void testBitfieldOversizedBeyondBoundary( @@ -5030,14 +4921,10 @@ struct BitfieldOversizedValueTypes { // ARM-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 2 // ARM-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63 // ARM-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 2 -// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// ARM-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 1 -// ARM-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 15 -// ARM-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 1 -// ARM-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// ARM-BE-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 2 -// ARM-BE-NEXT: [[TMP12:%.*]] = and i8 [[TMP11]], -15 -// ARM-BE-NEXT: store i8 [[TMP12]], ptr [[TMP10]], align 2 +// ARM-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// ARM-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 2 +// ARM-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 1 +// ARM-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 2 // ARM-BE-NEXT: ret void // // AARCH64-BE-LABEL: define dso_local void @testBitfieldOversizedValueTypes( @@ -5054,14 +4941,10 @@ struct BitfieldOversizedValueTypes { // AARCH64-BE-NEXT: [[TMP5:%.*]] = load i8, ptr [[TMP4]], align 2 // AARCH64-BE-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 63 // AARCH64-BE-NEXT: store i8 [[TMP6]], ptr [[TMP4]], align 2 -// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 1 -// AARCH64-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 1 -// AARCH64-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 15 -// AARCH64-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 1 -// AARCH64-BE-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 -// AARCH64-BE-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 2 -// AARCH64-BE-NEXT: [[TMP12:%.*]] = and i8 [[TMP11]], -15 -// AARCH64-BE-NEXT: store i8 [[TMP12]], ptr [[TMP10]], align 2 +// AARCH64-BE-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[TMP0]], i32 2 +// AARCH64-BE-NEXT: [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 2 +// AARCH64-BE-NEXT: [[TMP9:%.*]] = and i8 [[TMP8]], 1 +// AARCH64-BE-NEXT: store i8 [[TMP9]], ptr [[TMP7]], align 2 // AARCH64-BE-NEXT: ret void // extern "C" void testBitfieldOversizedValueTypes( >From a57f09dfe74547b919b2423d5e93db1803a020b8 Mon Sep 17 00:00:00 2001 From: Zile Xiong <[email protected]> Date: Wed, 23 Sep 2026 11:09:43 +0800 Subject: [PATCH 3/3] clang-format --- clang/lib/AST/ASTContext.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f2d7ebcbd3c5ed..c6554fc58f1985 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -15924,8 +15924,9 @@ struct PaddingCalculator { // are the low-order bits of the value container. const uint64_t ValueFieldBits = std::min(DeclaredSizeInBits, Ctx.getTypeSize(Field->getType())); - const uint64_t OccupiedSizeInBits = std::min( - ValueFieldBits, static_cast<uint64_t>(Ctx.getIntWidth(Field->getType()))); + const uint64_t OccupiedSizeInBits = + std::min(ValueFieldBits, + static_cast<uint64_t>(Ctx.getIntWidth(Field->getType()))); if (Ctx.getTargetInfo().isLittleEndian()) { OccuppiedIntervals.push_back( @@ -15946,8 +15947,7 @@ struct PaddingCalculator { // Within the value container, occupied bits are its low-order bits, which // are allocated last. Padding from an oversized declared width follows // the container. - const uint64_t Start = - StartBitOffset + ValueFieldBits - OccupiedSizeInBits; + const uint64_t Start = StartBitOffset + ValueFieldBits - OccupiedSizeInBits; const uint64_t End = Start + OccupiedSizeInBits; const uint64_t CharWidth = Ctx.getCharWidth(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
