Skip to content

Commit b347a72

Browse files
authored
[MC/DC][Coverage] Make tvbitmapupdate capable of atomic write (#96042)
This also introduces "Test and conditional Read-Modify-Write". The flow to `atomicrmw or` is marked as `unlikely`.
1 parent 896dd32 commit b347a72

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "llvm/IR/Instruction.h"
3939
#include "llvm/IR/Instructions.h"
4040
#include "llvm/IR/IntrinsicInst.h"
41+
#include "llvm/IR/MDBuilder.h"
4142
#include "llvm/IR/Module.h"
4243
#include "llvm/IR/Type.h"
4344
#include "llvm/InitializePasses.h"
@@ -967,6 +968,29 @@ Function *InstrLowerer::createRMWOrFunc() {
967968
// %mcdc.bits = load i8, ptr %4, align 1
968969
auto *Bitmap = Builder.CreateLoad(Int8Ty, ArgAddr, "mcdc.bits");
969970

971+
if (Options.Atomic || AtomicCounterUpdateAll) {
972+
// If ((Bitmap & Val) != Val), then execute atomic (Bitmap |= Val).
973+
// Note, just-loaded Bitmap might not be up-to-date. Use it just for
974+
// early testing.
975+
auto *Masked = Builder.CreateAnd(Bitmap, ArgVal);
976+
auto *ShouldStore = Builder.CreateICmpNE(Masked, ArgVal);
977+
auto *ThenTerm = BasicBlock::Create(Ctx, "", Fn);
978+
auto *ElseTerm = BasicBlock::Create(Ctx, "", Fn);
979+
// Assume updating will be rare.
980+
auto *Unlikely = MDBuilder(Ctx).createUnlikelyBranchWeights();
981+
Builder.CreateCondBr(ShouldStore, ThenTerm, ElseTerm, Unlikely);
982+
983+
IRBuilder<> ThenBuilder(ThenTerm);
984+
ThenBuilder.CreateAtomicRMW(AtomicRMWInst::Or, ArgAddr, ArgVal,
985+
MaybeAlign(), AtomicOrdering::Monotonic);
986+
ThenBuilder.CreateRetVoid();
987+
988+
IRBuilder<> ElseBuilder(ElseTerm);
989+
ElseBuilder.CreateRetVoid();
990+
991+
return Fn;
992+
}
993+
970994
// Perform logical OR of profile bitmap byte and shifted bit offset.
971995
// %8 = or i8 %mcdc.bits, %7
972996
auto *Result = Builder.CreateOr(Bitmap, ArgVal);

llvm/test/Instrumentation/InstrProfiling/mcdc.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; Check that MC/DC intrinsics are properly lowered
22
; RUN: opt < %s -passes=instrprof -S | FileCheck %s --check-prefixes=CHECK,BASIC
3+
; RUN: opt < %s -passes=instrprof -S -instrprof-atomic-counter-update-all | FileCheck %s --check-prefixes=CHECK,ATOMIC
34
; RUN: opt < %s -passes=instrprof -runtime-counter-relocation -S 2>&1 | FileCheck %s --check-prefix RELOC
45

56
; RELOC: Runtime counter relocation is presently not supported for MC/DC bitmaps
@@ -9,6 +10,7 @@ target triple = "x86_64-unknown-linux-gnu"
910
@__profn_test = private constant [4 x i8] c"test"
1011

1112
; BASIC: [[PROFBM_ADDR:@__profbm_test]] = private global [1 x i8] zeroinitializer, section "__llvm_prf_bits", comdat, align 1
13+
; ATOMIC: [[PROFBM_ADDR:@__profbm_test]] = private global [1 x i8] zeroinitializer, section "__llvm_prf_bits", comdat, align 1
1214

1315
define dso_local void @test(i32 noundef %A) {
1416
entry:
@@ -38,8 +40,17 @@ entry:
3840
; CHECK: %[[BITS:.+]] = load i8, ptr %[[ARGPTR]], align 1
3941
; BASIC-NEXT: %[[LAB11:[0-9]+]] = or i8 %[[BITS]], %[[ARGVAL]]
4042
; BASIC-NEXT: store i8 %[[LAB11]], ptr %[[ARGPTR]], align 1
43+
; ATOMIC-NEXT: %[[MASKED:.+]] = and i8 %[[BITS]], %[[ARGVAL]]
44+
; ATOMIC-NEXT: %[[SHOULDWRITE:.+]] = icmp ne i8 %[[MASKED]], %[[ARGVAL]]
45+
; ATOMIC-NEXT: br i1 %[[SHOULDWRITE]], label %[[WRITE:.+]], label %[[SKIP:.+]], !prof ![[MDPROF:[0-9]+]]
46+
; ATOMIC: [[WRITE]]:
47+
; ATOMIC-NEXT: %{{.+}} = atomicrmw or ptr %[[ARGPTR]], i8 %[[ARGVAL]] monotonic, align 1
48+
; ATOMIC-NEXT: ret void
49+
; ATOMIC: [[SKIP]]:
4150
; CHECK-NEXT: ret void
4251

52+
; ATOMIC: ![[MDPROF]] = !{!"branch_weights", i32 1, i32 1048575}
53+
4354
declare void @llvm.instrprof.cover(ptr, i64, i32, i32)
4455

4556
declare void @llvm.instrprof.mcdc.parameters(ptr, i64, i32)

0 commit comments

Comments
 (0)