diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -406,15 +406,17 @@ return; } - // Check if OffsetInRecord is better as a single field run. When OffsetInRecord - // has legal integer width, and its bitfield offset is naturally aligned, it - // is better to make the bitfield a separate storage component so as it can be - // accessed directly with lower cost. + // Check if OffsetInRecord (the size in bits of the current run) is better + // as a single field run. When OffsetInRecord has legal integer width, and + // its bitfield offset is naturally aligned, it is better to make the + // bitfield a separate storage component so as it can be accessed directly + // with lower cost. auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, uint64_t StartBitOffset) { if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) return false; - if (!DataLayout.isLegalInteger(OffsetInRecord)) + if (OffsetInRecord < 8 || !llvm::isPowerOf2_64(OffsetInRecord) || + !DataLayout.fitsInLegalInteger(OffsetInRecord)) return false; // Make sure StartBitOffset is natually aligned if it is treated as an // IType integer. diff --git a/clang/test/CodeGenCXX/finegrain-bitfield-type.cpp b/clang/test/CodeGenCXX/finegrain-bitfield-type.cpp --- a/clang/test/CodeGenCXX/finegrain-bitfield-type.cpp +++ b/clang/test/CodeGenCXX/finegrain-bitfield-type.cpp @@ -1,5 +1,12 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ // RUN: -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple riscv64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -o - %s | FileCheck %s + +// Note: This test checks the X86-64 and RISC-V targets in order to explore +// behaviour when i8/i16 are native integer widths (X86-64) and when they're +// not (RISC-V). + struct S4 { unsigned long f1:28; unsigned long f2:4; @@ -19,4 +26,4 @@ // CHECK: %struct.S4 = type { i32, i16 } // CHECK-NOT: %struct.S4 = type { i48 } // CHECK: %struct.S5 = type { i32, i32, i16, [6 x i8] } -// CHECK-NOT: %struct.S5 = type { i80 } \ No newline at end of file +// CHECK-NOT: %struct.S5 = type { i80 }