Index: clang/lib/CodeGen/CGRecordLayoutBuilder.cpp =================================================================== --- clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -414,7 +414,8 @@ 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. Index: clang/test/CodeGenCXX/finegrain-bitfield-type.cpp =================================================================== --- clang/test/CodeGenCXX/finegrain-bitfield-type.cpp +++ 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 }