diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1890,6 +1890,9 @@ if (CodeGenOpts.SpeculativeLoadHardening) FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening); + if (getTypes().getCodeGenOpts().FineGrainedBitfieldAccesses) + FuncAttrs.addAttribute(llvm::Attribute::FineGrainedBitfields); + // Add zero-call-used-regs attribute. switch (CodeGenOpts.getZeroCallUsedRegs()) { case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -984,6 +984,11 @@ Fn->addFnAttr(llvm::Attribute::StrictFP); } + // The fine grained bit-fields attribute is used to determine IPO inlining + // compatibility. + if (getTypes().getCodeGenOpts().FineGrainedBitfieldAccesses) + Fn->addFnAttr(llvm::Attribute::FineGrainedBitfields); + // If a custom alignment is used, force realigning to this alignment on // any main function which certainly will need it. if (FD && ((FD->isMain() || FD->isMSVCRTEntryPoint()) && diff --git a/clang/test/CodeGen/fine-grained-bitfield-accesses.c b/clang/test/CodeGen/fine-grained-bitfield-accesses.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/fine-grained-bitfield-accesses.c @@ -0,0 +1,21 @@ +// RUN: %clang -ffine-grained-bitfield-accesses -S -emit-llvm -o - %s | FileCheck %s +// CHECK: define{{.*}} @g(){{.*}} #[[GATTR:[0-9]+]] { +// CHECK: declare{{.*}} void @f(ptr noundef){{.*}} #[[FATTR:[0-9]+]] +// CHECK: attributes #[[GATTR]] = {{.*}} fine_grained_bitfields {{.*}} +// CHECK: attributes #[[FATTR]] = {{.*}} fine_grained_bitfields {{.*}} +// +// Verify that the clang fine-grained-bitfield-accesses option adds the IR +// function attribute fine_grained_bitfields. +struct X { + int a : 8; + int b : 24; +}; + +void f(struct X*); + +int g() { + struct X x; + x.a = 10; + f(&x); + return x.a; +}