[clang] [llvm] [Coverage] Introduce "partial fold" on BranchRegion (PR #112694)
NAKAMURA Takumi via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 17 04:40:57 PDT 2024
https://github.com/chapuni created https://github.com/llvm/llvm-project/pull/112694
Currently both True/False counts were folded. It lost the information, "It is True or False before folding." It prevented recalling branch counts in merging template instantiations.
In `llvm-cov`, a folded branch is shown as:
- `[True: n, Folded]`
- `[Folded, False n]`
In the case If `n` is zero, a branch is reported as "uncovered". This is distinguished from "folded" branch. When folded branches are merged, `Folded` may be dissolved.
In the coverage map, either `Counter` is `Zero`. Currently both were `Zero`.
Since "partial fold" has been introduced, either case in `switch` is omitted as `Folded`.
Each `case:` in `switch` is reported as `[True: n, Folded]`, since `False` count doesn't show meaningful value.
When `switch` doesn't have `default:`, `switch (Cond)` is reported as `[Folded, False: n]`, since `True` count was just the sum of `case`(s). `switch` with `default` can be considered as "the statement that doesn't have any `False`(s)".
>From ea3e2df8c712ae5da77e55a14e97b1b6855a6b76 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sun, 6 Oct 2024 10:11:54 +0900
Subject: [PATCH] [Coverage] Introduce "partial fold" on BranchRegion
Currently both True/False counts were folded. It lost the information,
"It is True or False before folding." It prevented recalling branch
counts in merging template instantiations.
In `llvm-cov`, a folded branch is shown as:
- `[True: n, Folded]`
- `[Folded, False n]`
In the case If `n` is zero, a branch is reported as "uncovered". This
is distinguished from "folded" branch. When folded branches are
merged, `Folded` may be dissolved.
In the coverage map, either `Counter` is `Zero`. Currently both were
`Zero`.
Since "partial fold" has been introduced, either case in `switch` is
omitted as `Folded`.
Each `case:` in `switch` is reported as `[True: n, Folded]`, since
`False` count doesn't show meaningful value.
When `switch` doesn't have `default:`, `switch (Cond)` is reported as
`[Folded, False: n]`, since `True` count was just the sum of
`case`(s). `switch` with `default` can be considered as "the statement
that doesn't have any `False`(s)".
---
clang/lib/CodeGen/CoverageMappingGen.cpp | 46 +++++--------
.../CoverageMapping/branch-constfolded.cpp | 40 ++++++------
clang/test/CoverageMapping/if.cpp | 4 +-
clang/test/CoverageMapping/macro-expansion.c | 10 +--
.../test/CoverageMapping/mcdc-scratch-space.c | 4 +-
.../CoverageMapping/mcdc-system-headers.cpp | 4 +-
clang/test/CoverageMapping/switch.cpp | 64 +++++++++----------
clang/test/CoverageMapping/switchmacro.c | 4 +-
.../ProfileData/Coverage/CoverageMapping.h | 15 +++--
.../ProfileData/Coverage/CoverageMapping.cpp | 2 +-
.../test/tools/llvm-cov/branch-c-general.test | 14 ++--
llvm/tools/llvm-cov/CoverageExporterJson.cpp | 2 +-
llvm/tools/llvm-cov/CoverageExporterLcov.cpp | 2 +-
llvm/tools/llvm-cov/CoverageSummaryInfo.cpp | 24 +++----
.../tools/llvm-cov/SourceCoverageViewHTML.cpp | 51 +++++++++------
.../tools/llvm-cov/SourceCoverageViewText.cpp | 47 ++++++++------
16 files changed, 169 insertions(+), 164 deletions(-)
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 07015834bc84f3..a9a3eb91a6af27 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1098,12 +1098,6 @@ struct CounterCoverageMappingBuilder
return ExitCount;
}
- /// Determine whether the given condition can be constant folded.
- bool ConditionFoldsToBool(const Expr *Cond) {
- Expr::EvalResult Result;
- return (Cond->EvaluateAsInt(Result, CVM.getCodeGenModule().getContext()));
- }
-
/// Create a Branch Region around an instrumentable condition for coverage
/// and add it to the function's SourceRegions. A branch region tracks a
/// "True" counter and a "False" counter for boolean expressions that
@@ -1133,13 +1127,15 @@ struct CounterCoverageMappingBuilder
// Alternatively, we can prevent any optimization done via
// constant-folding by ensuring that ConstantFoldsToSimpleInteger() in
// CodeGenFunction.c always returns false, but that is very heavy-handed.
- if (ConditionFoldsToBool(C))
- popRegions(pushRegion(Counter::getZero(), getStart(C), getEnd(C),
- Counter::getZero(), BranchParams));
- else
- // Otherwise, create a region with the True counter and False counter.
- popRegions(pushRegion(TrueCnt, getStart(C), getEnd(C), FalseCnt,
- BranchParams));
+ Expr::EvalResult Result;
+ if (C->EvaluateAsInt(Result, CVM.getCodeGenModule().getContext())) {
+ if (Result.Val.getInt().getBoolValue())
+ FalseCnt = Counter::getZero();
+ else
+ TrueCnt = Counter::getZero();
+ }
+ popRegions(
+ pushRegion(TrueCnt, getStart(C), getEnd(C), FalseCnt, BranchParams));
}
}
@@ -1153,12 +1149,12 @@ struct CounterCoverageMappingBuilder
/// Create a Branch Region around a SwitchCase for code coverage
/// and add it to the function's SourceRegions.
- void createSwitchCaseRegion(const SwitchCase *SC, Counter TrueCnt,
- Counter FalseCnt) {
+ void createSwitchCaseRegion(const SwitchCase *SC, Counter TrueCnt) {
// Push region onto RegionStack but immediately pop it (which adds it to
// the function's SourceRegions) because it doesn't apply to any other
// source other than the SwitchCase.
- popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(), FalseCnt));
+ popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(),
+ Counter::getZero()));
}
/// Check whether a region with bounds \c StartLoc and \c EndLoc
@@ -1870,24 +1866,16 @@ struct CounterCoverageMappingBuilder
const SwitchCase *Case = S->getSwitchCaseList();
for (; Case; Case = Case->getNextSwitchCase()) {
HasDefaultCase = HasDefaultCase || isa<DefaultStmt>(Case);
- CaseCountSum =
- addCounters(CaseCountSum, getRegionCounter(Case), /*Simplify=*/false);
- createSwitchCaseRegion(
- Case, getRegionCounter(Case),
- subtractCounters(ParentCount, getRegionCounter(Case)));
+ auto CaseCount = getRegionCounter(Case);
+ CaseCountSum = addCounters(CaseCountSum, CaseCount, /*Simplify=*/false);
+ createSwitchCaseRegion(Case, CaseCount);
}
- // Simplify is skipped while building the counters above: it can get really
- // slow on top of switches with thousands of cases. Instead, trigger
- // simplification by adding zero to the last counter.
- CaseCountSum = addCounters(CaseCountSum, Counter::getZero());
-
// If no explicit default case exists, create a branch region to represent
// the hidden branch, which will be added later by the CodeGen. This region
// will be associated with the switch statement's condition.
if (!HasDefaultCase) {
- Counter DefaultTrue = subtractCounters(ParentCount, CaseCountSum);
- Counter DefaultFalse = subtractCounters(ParentCount, DefaultTrue);
- createBranchRegion(S->getCond(), DefaultTrue, DefaultFalse);
+ Counter DefaultCount = subtractCounters(ParentCount, CaseCountSum);
+ createBranchRegion(S->getCond(), Counter::getZero(), DefaultCount);
}
}
diff --git a/clang/test/CoverageMapping/branch-constfolded.cpp b/clang/test/CoverageMapping/branch-constfolded.cpp
index 1e7e32808e8382..a2ac1c1eacd28f 100644
--- a/clang/test/CoverageMapping/branch-constfolded.cpp
+++ b/clang/test/CoverageMapping/branch-constfolded.cpp
@@ -5,94 +5,94 @@
// CHECK-LABEL: _Z6fand_0b:
bool fand_0(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
- return false && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
+ return false && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, (#0 - #1)
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:20 = #2, (#1 - #2)
// CHECK-LABEL: _Z6fand_1b:
bool fand_1(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
return a && true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #1, (#0 - #1)
-} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = 0, 0
+} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = #2, 0
// CHECK-LABEL: _Z6fand_2bb:
bool fand_2(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:25 = M:4, C:3
- return false && a && b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
+ return false && a && b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, (#0 - #3)
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:20 = #4, (#3 - #4)
// CHECK: Branch,File 0, [[@LINE-2]]:24 -> [[@LINE-2]]:25 = #2, (#1 - #2)
// CHECK-LABEL: _Z6fand_3bb:
bool fand_3(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:24 = M:4, C:3
return a && true && b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #3, (#0 - #3)
-} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = 0, 0
+} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = #4, 0
// CHECK: Branch,File 0, [[@LINE-2]]:23 -> [[@LINE-2]]:24 = #2, (#1 - #2)
// CHECK-LABEL: _Z6fand_4bb:
bool fand_4(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:25 = M:4, C:3
return a && b && false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #3, (#0 - #3)
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:16 = #4, (#3 - #4)
- // CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:25 = 0, 0
+ // CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:25 = 0, (#1 - #2)
// CHECK-LABEL: _Z6fand_5b:
bool fand_5(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:23 = M:3, C:2
- return false && true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
-} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:23 = 0, 0
+ return false && true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, (#0 - #1)
+} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:23 = #2, 0
// CHECK-LABEL: _Z6fand_6b:
bool fand_6(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
- return true && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
+ return true && a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = #1, 0
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:19 = #2, (#1 - #2)
// CHECK-LABEL: _Z6fand_7b:
bool fand_7(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
return a && false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = #1, (#0 - #1)
-} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, 0
+} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, (#1 - #2)
// CHECK-LABEL: _Z5for_0b:
bool for_0(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
- return true || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
+ return true || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = (#0 - #1), 0
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:19 = (#1 - #2), #2
// CHECK-LABEL: _Z5for_1b:
bool for_1(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
return a || false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #1), #1
-} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, 0
+} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, #2
// CHECK-LABEL: _Z5for_2bb:
bool for_2(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:24 = M:4, C:3
- return true || a || b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
+ return true || a || b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = (#0 - #3), 0
} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:19 = (#3 - #4), #4
// CHECK: Branch,File 0, [[@LINE-2]]:23 -> [[@LINE-2]]:24 = (#1 - #2), #2
// CHECK-LABEL: _Z5for_3bb:
bool for_3(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:25 = M:4, C:3
return a || false || b; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #3), #3
-} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, 0
+} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:20 = 0, #4
// CHECK: Branch,File 0, [[@LINE-2]]:24 -> [[@LINE-2]]:25 = (#1 - #2), #2
// CHECK-LABEL: _Z5for_4bb:
bool for_4(bool a, bool b) {// MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:24 = M:4, C:3
return a || b || true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #3), #3
} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:16 = (#3 - #4), #4
- // CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:24 = 0, 0
+ // CHECK: Branch,File 0, [[@LINE-2]]:20 -> [[@LINE-2]]:24 = (#1 - #2), 0
// CHECK-LABEL: _Z5for_5b:
bool for_5(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:23 = M:3, C:2
- return true || false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = 0, 0
-} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:23 = 0, 0
+ return true || false; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:14 = (#0 - #1), 0
+} // CHECK: Branch,File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:23 = 0, #2
// CHECK-LABEL: _Z5for_6b:
bool for_6(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:20 = M:3, C:2
- return false || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, 0
+ return false || a; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:15 = 0, #1
} // CHECK: Branch,File 0, [[@LINE-1]]:19 -> [[@LINE-1]]:20 = (#1 - #2), #2
// CHECK-LABEL: _Z5for_7b:
bool for_7(bool a) { // MCDC: Decision,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:19 = M:3, C:2
return a || true; // CHECK: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = (#0 - #1), #1
-} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = 0, 0
+} // CHECK: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:19 = (#1 - #2), 0
// CHECK-LABEL: _Z5for_8b:
bool for_8(bool a) { // MCDC: Decision,File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:20 = M:3, C:2
- // CHECK: Branch,File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:11 = 0, 0
- // CHECK: Branch,File 0, [[@LINE+1]]:15 -> [[@LINE+1]]:20 = 0, 0
+ // CHECK: Branch,File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:11 = #2, 0
+ // CHECK: Branch,File 0, [[@LINE+1]]:15 -> [[@LINE+1]]:20 = 0, (#2 - #3)
if (true && false)
return true;
else
diff --git a/clang/test/CoverageMapping/if.cpp b/clang/test/CoverageMapping/if.cpp
index 445cdfc20e2aff..b6fd525e930f90 100644
--- a/clang/test/CoverageMapping/if.cpp
+++ b/clang/test/CoverageMapping/if.cpp
@@ -14,7 +14,7 @@ struct S {
// CHECK-LABEL: _Z3foov:
// CHECK-NEXT: [[@LINE+3]]:12 -> [[@LINE+8]]:2 = #0
// CHECK-NEXT: [[@LINE+3]]:15 -> [[@LINE+3]]:19 = #0
- // CHECK-NEXT: Branch,File 0, [[@LINE+2]]:15 -> [[@LINE+2]]:19 = 0, 0
+ // CHECK-NEXT: Branch,File 0, [[@LINE+2]]:15 -> [[@LINE+2]]:19 = #2, 0
void foo() { // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:21 -> [[@LINE+1]]:22 = #2
if (int j = true ? nop() // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = #2
: nop(); // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = (#0 - #2)
@@ -168,7 +168,7 @@ int main() { // CHECK: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 =
// GH-45481
S s;
s.the_prop = 0? 1 : 2; // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE]]:17 = #0
- // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:17 = 0, 0
+ // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:17 = 0, (#0 - #7)
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:18 -> [[@LINE-2]]:19 = #7
// CHECK-NEXT: File 0, [[@LINE-3]]:19 -> [[@LINE-3]]:20 = #7
// CHECK-NEXT: File 0, [[@LINE-4]]:23 -> [[@LINE-4]]:24 = (#0 - #7)
diff --git a/clang/test/CoverageMapping/macro-expansion.c b/clang/test/CoverageMapping/macro-expansion.c
index ad71fb15eda423..4cd2c934371931 100644
--- a/clang/test/CoverageMapping/macro-expansion.c
+++ b/clang/test/CoverageMapping/macro-expansion.c
@@ -4,29 +4,29 @@
// CHECK: File 1, [[@LINE+7]]:12 -> [[@LINE+7]]:38 = #0
// CHECK-NEXT: File 1, [[@LINE+6]]:15 -> [[@LINE+6]]:28 = (#0 + #2)
// CHECK-NEXT: File 1, [[@LINE+5]]:21 -> [[@LINE+5]]:22 = (#0 + #2)
-// CHECK: Branch,File 1, [[@LINE+4]]:21 -> [[@LINE+4]]:22 = 0, 0
+// CHECK: Branch,File 1, [[@LINE+4]]:21 -> [[@LINE+4]]:22 = 0, ((#0 + #2) - #3)
// CHECK-NEXT: File 1, [[@LINE+3]]:24 -> [[@LINE+3]]:26 = #3
// CHECK-NEXT: File 1, [[@LINE+2]]:36 -> [[@LINE+2]]:37 = (#0 + #2)
-// CHECK-NEXT: Branch,File 1, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, 0
+// CHECK-NEXT: Branch,File 1, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, #0
#define M1 do { if (0) {} } while (0)
// CHECK-NEXT: File 2, [[@LINE+12]]:15 -> [[@LINE+12]]:41 = #0
// CHECK-NEXT: File 2, [[@LINE+11]]:18 -> [[@LINE+11]]:31 = (#0 + #4)
// CHECK-NEXT: File 2, [[@LINE+10]]:24 -> [[@LINE+10]]:25 = (#0 + #4)
// CHECK: File 2, [[@LINE+9]]:27 -> [[@LINE+9]]:29 = #5
// CHECK-NEXT: File 2, [[@LINE+8]]:39 -> [[@LINE+8]]:40 = (#0 + #4)
-// CHECK-NEXT: Branch,File 2, [[@LINE+7]]:39 -> [[@LINE+7]]:40 = 0, 0
+// CHECK-NEXT: Branch,File 2, [[@LINE+7]]:39 -> [[@LINE+7]]:40 = 0, #0
// CHECK-NEXT: File 3, [[@LINE+6]]:15 -> [[@LINE+6]]:41 = #0
// CHECK-NEXT: File 3, [[@LINE+5]]:18 -> [[@LINE+5]]:31 = (#0 + #6)
// CHECK-NEXT: File 3, [[@LINE+4]]:24 -> [[@LINE+4]]:25 = (#0 + #6)
// CHECK: File 3, [[@LINE+3]]:27 -> [[@LINE+3]]:29 = #7
// CHECK-NEXT: File 3, [[@LINE+2]]:39 -> [[@LINE+2]]:40 = (#0 + #6)
-// CHECK-NEXT: Branch,File 3, [[@LINE+1]]:39 -> [[@LINE+1]]:40 = 0, 0
+// CHECK-NEXT: Branch,File 3, [[@LINE+1]]:39 -> [[@LINE+1]]:40 = 0, #0
#define M2(x) do { if (x) {} } while (0)
// CHECK-NEXT: File 4, [[@LINE+5]]:15 -> [[@LINE+5]]:38 = #0
// CHECK-NEXT: File 4, [[@LINE+4]]:18 -> [[@LINE+4]]:28 = (#0 + #8)
// CHECK-NEXT: Expansion,File 4, [[@LINE+3]]:20 -> [[@LINE+3]]:22 = (#0 + #8)
// CHECK-NEXT: File 4, [[@LINE+2]]:36 -> [[@LINE+2]]:37 = (#0 + #8)
-// CHECK-NEXT: Branch,File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, 0
+// CHECK-NEXT: Branch,File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, #0
#define M3(x) do { M2(x); } while (0)
// CHECK-NEXT: File 5, [[@LINE+4]]:15 -> [[@LINE+4]]:27 = #0
// CHECK-NEXT: File 5, [[@LINE+3]]:16 -> [[@LINE+3]]:19 = #0
diff --git a/clang/test/CoverageMapping/mcdc-scratch-space.c b/clang/test/CoverageMapping/mcdc-scratch-space.c
index a263e9b688faed..60e456948a5182 100644
--- a/clang/test/CoverageMapping/mcdc-scratch-space.c
+++ b/clang/test/CoverageMapping/mcdc-scratch-space.c
@@ -3,7 +3,7 @@
// CHECK: builtin_macro0:
int builtin_macro0(int a) {
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:15 = M:3, C:2
- return (__LINE__ // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:11 = 0, 0 [1,2,0]
+ return (__LINE__ // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:11 = #1, 0 [1,2,0]
&& a); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:15 = #2, (#1 - #2) [2,0,0]
}
@@ -11,7 +11,7 @@ int builtin_macro0(int a) {
int builtin_macro1(int a) {
// CHECK: Decision,File 0, [[@LINE+1]]:11 -> [[@LINE+2]]:22 = M:3, C:2
return (a // CHECK: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = (#0 - #1), #1 [1,0,2]
- || __LINE__); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:14 = 0, 0 [2,0,0]
+ || __LINE__); // CHECK: Branch,File 0, [[@LINE]]:14 -> [[@LINE]]:14 = (#1 - #2), 0 [2,0,0]
}
#define PRE(x) pre_##x
diff --git a/clang/test/CoverageMapping/mcdc-system-headers.cpp b/clang/test/CoverageMapping/mcdc-system-headers.cpp
index ae26ed5fe469f2..cb1c8743c36e82 100644
--- a/clang/test/CoverageMapping/mcdc-system-headers.cpp
+++ b/clang/test/CoverageMapping/mcdc-system-headers.cpp
@@ -17,10 +17,10 @@
int func0(int a) {
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:21 = M:3, C:2
// W_SYS: Expansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = #0 (Expanded file = 1)
- // X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = 0, 0 [1,2,0]
+ // X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = #1, 0 [1,2,0]
return (CONST && a);
// CHECK: Branch,File 0, [[@LINE-1]]:20 -> [[@LINE-1]]:21 = #2, (#1 - #2) [2,0,0]
- // W_SYS: Branch,File 1, [[@LINE-16]]:15 -> [[@LINE-16]]:17 = 0, 0 [1,2,0]
+ // W_SYS: Branch,File 1, [[@LINE-16]]:15 -> [[@LINE-16]]:17 = #1, 0 [1,2,0]
}
// CHECK: _Z5func1ii:
diff --git a/clang/test/CoverageMapping/switch.cpp b/clang/test/CoverageMapping/switch.cpp
index b47c0e80099527..a1fee644faaf0e 100644
--- a/clang/test/CoverageMapping/switch.cpp
+++ b/clang/test/CoverageMapping/switch.cpp
@@ -2,13 +2,13 @@
// CHECK: foo
void foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = #0
- switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = ((#0 - #2) - #3), (#2 + #3)
+ switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = 0, ((#0 - #2) - #3)
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+5]]:10 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:11 = #2
- return; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
+ return; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:12 -> [[@LINE+1]]:3 = 0
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #3
- break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
+ break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
} // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE+1]]:3 = #1
int x = 0; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
@@ -18,24 +18,24 @@ int nop() { return 0; }
// CHECK: bar
void bar(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+21]]:2 = #0
- switch (i) // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = #0, 0
+ switch (i) // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = 0, #0
; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:6 = 0
switch (i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+17]]:2 = #1
- } // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = #1, 0
+ } // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = 0, #1
switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+14]]:2 = #2
- nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = #2, 0
+ nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = 0, #2
// CHECK-NEXT: File 0, [[@LINE-1]]:5 -> [[@LINE-1]]:10 = 0
switch (i) // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+11]]:2 = #3
- case 1: // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = (#3 - #5), #5
+ case 1: // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:11 -> [[@LINE-1]]:12 = 0, (#3 - #5)
// CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE+1]]:10 = #5
- nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #5, (#3 - #5)
+ nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #5, 0
// CHECK-NEXT: File 0, [[@LINE+1]]:3 -> [[@LINE+7]]:2 = #4
- switch (i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = (#4 - #7), #7
+ switch (i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = 0, (#4 - #7)
nop(); // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+2]]:10 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #7
- nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, (#4 - #7)
+ nop(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, 0
}
nop(); // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #6
}
@@ -44,7 +44,7 @@ void bar(int i) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+21]]:2 = #0
void baz() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
switch (int i = true ? nop() // CHECK: [[@LINE]]:26 -> [[@LINE]]:31 = #2
: nop(); // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = (#0 - #2)
- i) {} // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = #0, 0
+ i) {} // CHECK-NEXT: Branch,File 0, [[@LINE]]:11 -> [[@LINE]]:12 = 0, #0
nop(); // CHECK-NEXT: [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
}
@@ -53,35 +53,35 @@ int main() { // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+39]]:2 = #0
int i = 0;
switch(i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+8]]:10 = 0
case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #2
- i = 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
+ i = 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
break; // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:3 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #3
- i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
+ i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
break; // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:3 = 0
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #4
- break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #4, (#0 - #4)
+ break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #4, 0
} // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE+1]]:3 = #1
switch(i) { // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+27]]:2 = #1
case 0: // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+7]]:10 = 0
i = 1; // CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE+1]]:10 = #6
- break; // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #6, (#1 - #6)
+ break; // CHECK-NEXT: Branch,File 0, [[@LINE-2]]:3 -> [[@LINE-2]]:9 = #6, 0
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #7
- i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, (#1 - #7)
+ i = 2; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #7, 0
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = (#7 + #8)
- break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #8, (#1 - #8)
+ break; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #8, 0
} // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:3 = #5
// CHECK-NEXT: File 0, [[@LINE+1]]:3 -> [[@LINE+17]]:2 = #5
- switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = ((((#5 - #10) - #11) - #12) - #13), (((#10 + #11) + #12) + #13)
+ switch(i) { // CHECK-NEXT: Branch,File 0, [[@LINE]]:10 -> [[@LINE]]:11 = 0, ((((#5 - #10) - #11) - #12) - #13)
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+8]]:11 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+7]]:11 = #10
- // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #10, (#5 - #10)
+ // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #10, 0
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:11 = (#10 + #11)
- i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #11, (#5 - #11)
+ i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #11, 0
case 3: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:11 = ((#10 + #11) + #12)
- // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #12, (#5 - #12)
+ // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #12, 0
case 4: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:11 = (((#10 + #11) + #12) + #13)
- i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #13, (#5 - #13)
+ i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #13, 0
}
foo(1); // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:11 = #9
@@ -95,10 +95,10 @@ int pr44011(int i) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> {{.*}}:2 = #0
switch (i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> [[@LINE+6]]:13 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13 = #2
- return 0; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
+ return 0; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = 0
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13 = #3
- return 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #3, (#0 - #3)
+ return 1; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #3, 0
}
} // A region for counter #1 is missing due to the missing return.
@@ -106,17 +106,17 @@ int pr44011(int i) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> {{.*}}:2 = #0
// FIXME: End location for "case 1" shouldn't point at the end of the switch.
// CHECK: fallthrough
int fallthrough(int i) { // CHECK-NEXT: File 0, [[@LINE]]:24 -> [[@LINE+14]]:2 = #0
- // CHECK-NEXT: Branch,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:11 = ((((#0 - #2) - #3) - #4) - #5), (((#2 + #3) + #4) + #5)
+ // CHECK-NEXT: Branch,File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:11 = 0, ((((#0 - #2) - #3) - #4) - #5)
switch(i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+10]]:10 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+9]]:10 = #2
- i = 23; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, (#0 - #2)
+ i = 23; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #2, 0
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#2 + #3)
- i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
+ i = 11; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
break; // CHECK-NEXT: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:3 = 0
case 3: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:10 = #4
- // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, (#0 - #4)
+ // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, 0
case 4: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#4 + #5)
- i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #5, (#0 - #5)
+ i = 99; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #5, 0
break;
}
}
@@ -126,12 +126,12 @@ void abort(void) __attribute((noreturn));
int noret(int x) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+11]]:2
switch (x) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> [[@LINE+8]]:14 = 0
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:12
- abort(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, (#0 - #2)
+ abort(); // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, 0
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:3 = 0
case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13
- return 5; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, (#0 - #3)
+ return 5; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #3, 0
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = 0
case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:14
- return 10; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, (#0 - #4)
+ return 10; // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, 0
}
}
diff --git a/clang/test/CoverageMapping/switchmacro.c b/clang/test/CoverageMapping/switchmacro.c
index 4c98cc7d9403a4..0696e7490cdf99 100644
--- a/clang/test/CoverageMapping/switchmacro.c
+++ b/clang/test/CoverageMapping/switchmacro.c
@@ -6,7 +6,7 @@
int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0
switch (i) { // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> {{[0-9]+}}:11 = 0
default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> {{[0-9]+}}:11 = #2
- // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, (#0 - #2)
+ // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = #2, 0
if (i == 1) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = #2
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = #3, (#2 - #3)
return 0; // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3
@@ -15,7 +15,7 @@ int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> {{[0-9]+}}:2 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> {{[0-9]+}}:11 = (#2 - #3)
FOO(1);
case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:13 = ((#2 + #4) - #3)
- // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, (#0 - #4)
+ // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = #4, 0
return 2; // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> [[@LINE+4]]:3 = 0
// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = 0
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index fa07b3a9e8b14f..e952b04fce7b34 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -358,20 +358,21 @@ struct CounterMappingRegion {
struct CountedRegion : public CounterMappingRegion {
uint64_t ExecutionCount;
uint64_t FalseExecutionCount;
- bool Folded;
+ bool TrueFolded;
+ bool FalseFolded;
bool HasSingleByteCoverage;
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
bool HasSingleByteCoverage)
: CounterMappingRegion(R), ExecutionCount(ExecutionCount),
- FalseExecutionCount(0), Folded(false),
+ FalseExecutionCount(0), TrueFolded(false), FalseFolded(true),
HasSingleByteCoverage(HasSingleByteCoverage) {}
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
uint64_t FalseExecutionCount, bool HasSingleByteCoverage)
: CounterMappingRegion(R), ExecutionCount(ExecutionCount),
- FalseExecutionCount(FalseExecutionCount), Folded(false),
- HasSingleByteCoverage(HasSingleByteCoverage) {}
+ FalseExecutionCount(FalseExecutionCount), TrueFolded(false),
+ FalseFolded(false), HasSingleByteCoverage(HasSingleByteCoverage) {}
};
/// MCDC Record grouping all information together.
@@ -719,10 +720,10 @@ struct FunctionRecord {
Region.Kind == CounterMappingRegion::MCDCBranchRegion) {
CountedBranchRegions.emplace_back(Region, Count, FalseCount,
HasSingleByteCoverage);
- // If both counters are hard-coded to zero, then this region represents a
+ // If either counters is hard-coded to zero, then this region represents a
// constant-folded branch.
- if (Region.Count.isZero() && Region.FalseCount.isZero())
- CountedBranchRegions.back().Folded = true;
+ CountedBranchRegions.back().TrueFolded = Region.Count.isZero();
+ CountedBranchRegions.back().FalseFolded = Region.FalseCount.isZero();
return;
}
if (CountedRegions.empty())
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index c713371da81e40..119e09187b9080 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -503,7 +503,7 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
const auto &BranchParams = B->getBranchParams();
PosToID[I] = BranchParams.ID;
CondLoc[I] = B->startLoc();
- Folded[I++] = (B->Count.isZero() && B->FalseCount.isZero());
+ Folded[I++] = (B->Count.isZero() || B->FalseCount.isZero());
}
// Using Profile Bitmap from runtime, mark the executed test vectors.
diff --git a/llvm/test/tools/llvm-cov/branch-c-general.test b/llvm/test/tools/llvm-cov/branch-c-general.test
index 9b5889babde366..2fa99dfe61532e 100644
--- a/llvm/test/tools/llvm-cov/branch-c-general.test
+++ b/llvm/test/tools/llvm-cov/branch-c-general.test
@@ -47,7 +47,7 @@
// CHECK: Branch (103:9): [True: 9, False: 1]
// CHECK: switches()
-// CHECK: Branch (113:3): [True: 1, False: 0]
+// CHECK: Branch (113:3): [True: 1, Folded]
// CHECK: Branch (117:63): [True: 15, False: 0]
// CHECK: Branch (119:5): [True: 1, False: 14]
// CHECK: Branch (120:11): [True: 0, False: 1]
@@ -57,7 +57,7 @@
// CHECK: Branch (126:11): [True: 3, False: 0]
// CHECK: Branch (128:5): [True: 4, False: 11]
// CHECK: Branch (129:11): [True: 4, False: 0]
-// CHECK: Branch (131:7): [True: 4, False: 0]
+// CHECK: Branch (131:7): [True: 4, Folded]
// CHECK: Branch (132:13): [True: 4, False: 0]
// CHECK: Branch (136:5): [True: 5, False: 10]
// CHECK: Branch (137:11): [True: 1, False: 4]
@@ -114,13 +114,13 @@
-// REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover
+// REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover
// REPORT-NEXT: ---
// REPORT-NEXT: simple_loops 8 0 100.00% 9 0 100.00% 6 0 100.00%
// REPORT-NEXT: conditionals 24 0 100.00% 15 0 100.00% 16 2 87.50%
// REPORT-NEXT: early_exits 20 4 80.00% 25 2 92.00% 16 6 62.50%
// REPORT-NEXT: jumps 39 12 69.23% 48 2 95.83% 26 9 65.38%
-// REPORT-NEXT: switches 28 5 82.14% 38 4 89.47% 30 9 70.00%
+// REPORT-NEXT: switches 28 5 82.14% 38 4 89.47% 28 7 75.00%
// REPORT-NEXT: big_switch 25 1 96.00% 32 0 100.00% 30 6 80.00%
// REPORT-NEXT: boolean_operators 16 0 100.00% 13 0 100.00% 22 2 90.91%
// REPORT-NEXT: boolop_loops 19 0 100.00% 14 0 100.00% 16 2 87.50%
@@ -129,12 +129,12 @@
// REPORT-NEXT: main 1 0 100.00% 16 0 100.00% 0 0 0.00%
// REPORT-NEXT: c-general.c:static_func 4 0 100.00% 4 0 100.00% 2 0 100.00%
// REPORT-NEXT: ---
-// REPORT-NEXT: TOTAL 197 24 87.82% 234 8 96.58% 174 38 78.16%
+// REPORT-NEXT: TOTAL 197 24 87.82% 234 8 96.58% 172 36 79.07%
// Test file-level report.
// RUN: llvm-profdata merge %S/Inputs/branch-c-general.proftext -o %t.profdata
// RUN: llvm-cov report %S/Inputs/branch-c-general.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-c-general.c | FileCheck %s -check-prefix=FILEREPORT
-// FILEREPORT: TOTAL{{.*}}174 38 78.16%
+// FILEREPORT: TOTAL{{.*}}172 36 79.07%
// Test color True/False output.
// RUN: llvm-cov show --use-color --show-branches=count %S/Inputs/branch-c-general.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-c-general.c | FileCheck %s -check-prefix=USECOLOR
@@ -161,6 +161,6 @@
// HTML-INDEX: <td class='column-entry-yellow'>
// HTML-INDEX: 87.82% (173/197)
// HTML-INDEX: <td class='column-entry-red'>
-// HTML-INDEX: 78.16% (136/174)
+// HTML-INDEX: 79.07% (136/172)
// HTML-INDEX: <tr class='light-row-bold'>
// HTML-INDEX: Totals
diff --git a/llvm/tools/llvm-cov/CoverageExporterJson.cpp b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
index 9a8c7c94f06124..4088c1b053aa8d 100644
--- a/llvm/tools/llvm-cov/CoverageExporterJson.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
@@ -125,7 +125,7 @@ json::Array renderRegions(ArrayRef<coverage::CountedRegion> Regions) {
json::Array renderBranchRegions(ArrayRef<coverage::CountedRegion> Regions) {
json::Array RegionArray;
for (const auto &Region : Regions)
- if (!Region.Folded)
+ if (!Region.TrueFolded || !Region.FalseFolded)
RegionArray.push_back(renderBranch(Region));
return RegionArray;
}
diff --git a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
index ae8f556edb313b..d6b9367ae4c514 100644
--- a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
@@ -139,7 +139,7 @@ void renderBranchExecutionCounts(raw_ostream &OS,
unsigned BranchIndex = 0;
while (NextBranch != EndBranch && CurrentLine == NextBranch->LineStart) {
- if (!NextBranch->Folded) {
+ if (!NextBranch->TrueFolded || !NextBranch->FalseFolded) {
unsigned BC1 = NextBranch->ExecutionCount;
unsigned BC2 = NextBranch->FalseExecutionCount;
bool BranchNotExecuted = (BC1 == 0 && BC2 == 0);
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index 4f150020ee3815..58e7918d392709 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -19,18 +19,18 @@ using namespace coverage;
static void sumBranches(size_t &NumBranches, size_t &CoveredBranches,
const ArrayRef<CountedRegion> &Branches) {
for (const auto &BR : Branches) {
- // Skip folded branches.
- if (BR.Folded)
- continue;
-
- // "True" Condition Branches.
- ++NumBranches;
- if (BR.ExecutionCount > 0)
- ++CoveredBranches;
- // "False" Condition Branches.
- ++NumBranches;
- if (BR.FalseExecutionCount > 0)
- ++CoveredBranches;
+ if (!BR.TrueFolded) {
+ // "True" Condition Branches.
+ ++NumBranches;
+ if (BR.ExecutionCount > 0)
+ ++CoveredBranches;
+ }
+ if (!BR.FalseFolded) {
+ // "False" Condition Branches.
+ ++NumBranches;
+ if (BR.FalseExecutionCount > 0)
+ ++CoveredBranches;
+ }
}
}
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index 6f4d327679d6b6..7421763dd7a427 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -1128,36 +1128,45 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
"line-number") +
"): [";
- if (R.Folded) {
+ if (R.TrueFolded && R.FalseFolded) {
OS << "Folded - Ignored]\n";
continue;
}
// Display TrueCount or TruePercent.
- std::string TrueColor = R.ExecutionCount ? "None" : "red branch";
+ std::string TrueColor =
+ (R.TrueFolded || R.ExecutionCount ? "None" : "red branch");
std::string TrueCovClass =
- (R.ExecutionCount > 0) ? "covered-line" : "uncovered-line";
-
- OS << tag("span", "True", TrueColor);
- OS << ": ";
- if (getOptions().ShowBranchCounts)
- OS << tag("span", formatCount(R.ExecutionCount), TrueCovClass) << ", ";
- else
- OS << format("%0.2f", TruePercent) << "%, ";
+ (R.TrueFolded || R.ExecutionCount > 0 ? "covered-line"
+ : "uncovered-line");
+
+ if (R.TrueFolded)
+ OS << "Folded, ";
+ else {
+ OS << tag("span", "True", TrueColor) << ": ";
+ if (getOptions().ShowBranchCounts)
+ OS << tag("span", formatCount(R.ExecutionCount), TrueCovClass) << ", ";
+ else
+ OS << format("%0.2f", TruePercent) << "%, ";
+ }
// Display FalseCount or FalsePercent.
- std::string FalseColor = R.FalseExecutionCount ? "None" : "red branch";
+ std::string FalseColor =
+ (R.FalseFolded || R.FalseExecutionCount ? "None" : "red branch");
std::string FalseCovClass =
- (R.FalseExecutionCount > 0) ? "covered-line" : "uncovered-line";
-
- OS << tag("span", "False", FalseColor);
- OS << ": ";
- if (getOptions().ShowBranchCounts)
- OS << tag("span", formatCount(R.FalseExecutionCount), FalseCovClass);
- else
- OS << format("%0.2f", FalsePercent) << "%";
-
- OS << "]\n";
+ (R.FalseFolded || R.FalseExecutionCount > 0 ? "covered-line"
+ : "uncovered-line");
+
+ if (R.FalseFolded)
+ OS << "Folded]\n";
+ else {
+ OS << tag("span", "False", FalseColor) << ": ";
+ if (getOptions().ShowBranchCounts)
+ OS << tag("span", formatCount(R.FalseExecutionCount), FalseCovClass)
+ << "]\n";
+ else
+ OS << format("%0.2f", FalsePercent) << "%]\n";
+ }
}
OS << EndPre;
OS << EndExpansionDiv;
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
index 8b93b592910b3d..444f33dac10837 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
@@ -309,31 +309,38 @@ void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV,
renderLinePrefix(OS, ViewDepth);
OS << " Branch (" << R.LineStart << ":" << R.ColumnStart << "): [";
- if (R.Folded) {
+ if (R.TrueFolded && R.FalseFolded) {
OS << "Folded - Ignored]\n";
continue;
}
- colored_ostream(OS, raw_ostream::RED,
- getOptions().Colors && !R.ExecutionCount,
- /*Bold=*/false, /*BG=*/true)
- << "True";
-
- if (getOptions().ShowBranchCounts)
- OS << ": " << formatCount(R.ExecutionCount) << ", ";
- else
- OS << ": " << format("%0.2f", TruePercent) << "%, ";
-
- colored_ostream(OS, raw_ostream::RED,
- getOptions().Colors && !R.FalseExecutionCount,
- /*Bold=*/false, /*BG=*/true)
- << "False";
+ if (R.TrueFolded)
+ OS << "Folded, ";
+ else {
+ colored_ostream(OS, raw_ostream::RED,
+ getOptions().Colors && !R.ExecutionCount,
+ /*Bold=*/false, /*BG=*/true)
+ << "True";
+
+ if (getOptions().ShowBranchCounts)
+ OS << ": " << formatCount(R.ExecutionCount) << ", ";
+ else
+ OS << ": " << format("%0.2f", TruePercent) << "%, ";
+ }
- if (getOptions().ShowBranchCounts)
- OS << ": " << formatCount(R.FalseExecutionCount);
- else
- OS << ": " << format("%0.2f", FalsePercent) << "%";
- OS << "]\n";
+ if (R.FalseFolded)
+ OS << "Folded]\n";
+ else {
+ colored_ostream(OS, raw_ostream::RED,
+ getOptions().Colors && !R.FalseExecutionCount,
+ /*Bold=*/false, /*BG=*/true)
+ << "False";
+
+ if (getOptions().ShowBranchCounts)
+ OS << ": " << formatCount(R.FalseExecutionCount) << "]\n";
+ else
+ OS << ": " << format("%0.2f", FalsePercent) << "%]\n";
+ }
}
}
More information about the cfe-commits
mailing list