Skip to content

Commit db1ee85

Browse files
committed
Fix tbaa.struct metadata for bitfields using big endian.
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. This breaks for big endian.
1 parent 67d2041 commit db1ee85

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 5 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,10 @@ 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+
bool IsBE = Context.getTargetInfo().isBigEndian();
324+
bool IsFirst = IsBE ? Info.StorageSize - (Info.Offset + Info.Size) == 0
325+
: Info.Offset == 0;
326+
if (!IsFirst)
323327
continue;
324328
unsigned CurrentBitFieldSize = Info.StorageSize;
325329
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)