Skip to content

Commit f905935

Browse files
authored
Fix tbaa.struct metadata for bitfields using big endian. (#87753)
When generating tbaa.struct metadata we treat multiple adjacent bitfields as a single "field", with one corresponding entry in the metadata. At the moment this is achieved by adding an entry for the first bitfield in the run using its StorageSize and skipping the remaining bitfields. The problem is that "first" is determined by checking that the Offset of the field in the run is 0, which breaks for big endian. PR: #87753
1 parent 3c3e0e5 commit f905935

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/AST/Mangle.h"
2323
#include "clang/AST/RecordLayout.h"
2424
#include "clang/Basic/CodeGenOptions.h"
25+
#include "clang/Basic/TargetInfo.h"
2526
#include "llvm/ADT/SmallSet.h"
2627
#include "llvm/IR/Constants.h"
2728
#include "llvm/IR/LLVMContext.h"
@@ -319,7 +320,13 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
319320
// base type.
320321
if ((*i)->isBitField()) {
321322
const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*i);
322-
if (Info.Offset != 0)
323+
// For big endian targets the first bitfield in the consecutive run is
324+
// at the most-significant end; see CGRecordLowering::setBitFieldInfo
325+
// for more information.
326+
bool IsBE = Context.getTargetInfo().isBigEndian();
327+
bool IsFirst = IsBE ? Info.StorageSize - (Info.Offset + Info.Size) == 0
328+
: Info.Offset == 0;
329+
if (!IsFirst)
323330
continue;
324331
unsigned CurrentBitFieldSize = Info.StorageSize;
325332
uint64_t Size =

clang/test/CodeGen/tbaa-struct-bitfield-endianness.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
// RUN: %clang_cc1 -triple aarch64_be-apple-darwin -emit-llvm -o - -O1 %s | \
2-
// RUN: FileCheck -check-prefixes=CHECK,CHECK-BE %s
2+
// RUN: FileCheck -check-prefixes=CHECK %s
33
// RUN: %clang_cc1 -triple aarch64-apple-darwin -emit-llvm -o - -O1 %s | \
4-
// RUN: FileCheck -check-prefixes=CHECK,CHECK-LE %s
4+
// RUN: FileCheck -check-prefixes=CHECK %s
55
//
66
// Check that TBAA metadata for structs containing bitfields is
77
// consistent between big and little endian layouts.
8-
//
9-
// FIXME: The metadata below is invalid for the big endian layout: the
10-
// start offset of 2 is incorrect.
118

129
struct NamedBitfields {
1310
int f1 : 8;
@@ -28,8 +25,7 @@ void copy(NamedBitfields *a1, NamedBitfields *a2) {
2825
*a1 = *a2;
2926
}
3027

31-
// CHECK-BE: [[TBAA_STRUCT2]] = !{i64 2, i64 4, [[META3:![0-9]+]], i64 4, i64 4, [[META6:![0-9]+]], i64 8, i64 8, [[META8:![0-9]+]]}
32-
// CHECK-LE: [[TBAA_STRUCT2]] = !{i64 0, i64 4, [[META3:![0-9]+]], i64 4, i64 4, [[META6:![0-9]+]], i64 8, i64 8, [[META8:![0-9]+]]}
28+
// CHECK: [[TBAA_STRUCT2]] = !{i64 0, i64 4, [[META3:![0-9]+]], i64 4, i64 4, [[META6:![0-9]+]], i64 8, i64 8, [[META8:![0-9]+]]}
3329
// CHECK: [[META3]] = !{[[META4:![0-9]+]], [[META4]], i64 0}
3430
// CHECK: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
3531
// CHECK: [[META5]] = !{!"Simple C++ TBAA"}

0 commit comments

Comments
 (0)