[llvm] llvm-cov: Calculate RegionCoverage based on `CoverageData::Segments` (PR #121191)

NAKAMURA Takumi via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 10 02:35:22 PST 2025


https://github.com/chapuni updated https://github.com/llvm/llvm-project/pull/121191

>From 978070d6aca594a49dc2ef0558e1e28e883ac1b0 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Fri, 27 Dec 2024 15:34:16 +0900
Subject: [PATCH 1/4] [Coverage] MCDC: Move `findIndependencePairs` into
 `MCDCRecord`

---
 .../ProfileData/Coverage/CoverageMapping.h    | 27 +++++---
 .../ProfileData/Coverage/CoverageMapping.cpp  | 67 ++++++++++---------
 2 files changed, 51 insertions(+), 43 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index 42da188fef34ee..4f28f5da6cf81f 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -35,6 +35,7 @@
 #include <cstdint>
 #include <iterator>
 #include <memory>
+#include <optional>
 #include <sstream>
 #include <string>
 #include <system_error>
@@ -451,19 +452,22 @@ struct MCDCRecord {
 private:
   CounterMappingRegion Region;
   TestVectors TV;
-  TVPairMap IndependencePairs;
+  std::optional<TVPairMap> IndependencePairs;
   BoolVector Folded;
   CondIDMap PosToID;
   LineColPairMap CondLoc;
 
 public:
   MCDCRecord(const CounterMappingRegion &Region, TestVectors &&TV,
-             TVPairMap &&IndependencePairs, BoolVector &&Folded,
-             CondIDMap &&PosToID, LineColPairMap &&CondLoc)
-      : Region(Region), TV(std::move(TV)),
-        IndependencePairs(std::move(IndependencePairs)),
-        Folded(std::move(Folded)), PosToID(std::move(PosToID)),
-        CondLoc(std::move(CondLoc)){};
+             BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
+      : Region(Region), TV(std::move(TV)), Folded(std::move(Folded)),
+        PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) {
+    findIndependencePairs();
+  }
+
+  // Compare executed test vectors against each other to find an independence
+  // pairs for each condition.  This processing takes the most time.
+  void findIndependencePairs();
 
   const CounterMappingRegion &getDecisionRegion() const { return Region; }
   unsigned getNumConditions() const {
@@ -494,10 +498,10 @@ struct MCDCRecord {
   /// TestVectors requires a translation from a ordinal position to actual
   /// condition ID. This is done via PosToID[].
   bool isConditionIndependencePairCovered(unsigned Condition) const {
+    assert(IndependencePairs);
     auto It = PosToID.find(Condition);
-    if (It != PosToID.end())
-      return IndependencePairs.contains(It->second);
-    llvm_unreachable("Condition ID without an Ordinal mapping");
+    assert(It != PosToID.end() && "Condition ID without an Ordinal mapping");
+    return IndependencePairs->contains(It->second);
   }
 
   /// Return the Independence Pair that covers the given condition. Because
@@ -507,7 +511,8 @@ struct MCDCRecord {
   /// via PosToID[].
   TVRowPair getConditionIndependencePair(unsigned Condition) {
     assert(isConditionIndependencePairCovered(Condition));
-    return IndependencePairs[PosToID[Condition]];
+    assert(IndependencePairs);
+    return (*IndependencePairs)[PosToID[Condition]];
   }
 
   float getPercentCovered() const {
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 87d8bb1bbb79c7..2c7a77bac09328 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -221,6 +221,40 @@ Expected<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
   return LastPoppedValue;
 }
 
+// Find an independence pair for each condition:
+// - The condition is true in one test and false in the other.
+// - The decision outcome is true one test and false in the other.
+// - All other conditions' values must be equal or marked as "don't care".
+void MCDCRecord::findIndependencePairs() {
+  if (IndependencePairs)
+    return;
+
+  IndependencePairs.emplace();
+
+  unsigned NumTVs = TV.size();
+  // Will be replaced to shorter expr.
+  unsigned TVTrueIdx = std::distance(
+      TV.begin(),
+      std::find_if(TV.begin(), TV.end(),
+                   [&](auto I) { return (I.second == MCDCRecord::MCDC_True); })
+
+  );
+  for (unsigned I = TVTrueIdx; I < NumTVs; ++I) {
+    const auto &[A, ACond] = TV[I];
+    assert(ACond == MCDCRecord::MCDC_True);
+    for (unsigned J = 0; J < TVTrueIdx; ++J) {
+      const auto &[B, BCond] = TV[J];
+      assert(BCond == MCDCRecord::MCDC_False);
+      // If the two vectors differ in exactly one condition, ignoring DontCare
+      // conditions, we have found an independence pair.
+      auto AB = A.getDifferences(B);
+      if (AB.count() == 1)
+        IndependencePairs->insert(
+            {AB.find_first(), std::make_pair(J + 1, I + 1)});
+    }
+  }
+}
+
 mcdc::TVIdxBuilder::TVIdxBuilder(const SmallVectorImpl<ConditionIDs> &NextIDs,
                                  int Offset)
     : Indices(NextIDs.size()) {
@@ -375,9 +409,6 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
   /// ExecutedTestVectorBitmap.
   MCDCRecord::TestVectors &ExecVectors;
 
-  /// Number of False items in ExecVectors
-  unsigned NumExecVectorsF;
-
 #ifndef NDEBUG
   DenseSet<unsigned> TVIdxs;
 #endif
@@ -446,34 +477,11 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
     // Fill ExecVectors order by False items and True items.
     // ExecVectors is the alias of ExecVectorsByCond[false], so
     // Append ExecVectorsByCond[true] on it.
-    NumExecVectorsF = ExecVectors.size();
     auto &ExecVectorsT = ExecVectorsByCond[true];
     ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()),
                        std::make_move_iterator(ExecVectorsT.end()));
   }
 
-  // Find an independence pair for each condition:
-  // - The condition is true in one test and false in the other.
-  // - The decision outcome is true one test and false in the other.
-  // - All other conditions' values must be equal or marked as "don't care".
-  void findIndependencePairs() {
-    unsigned NumTVs = ExecVectors.size();
-    for (unsigned I = NumExecVectorsF; I < NumTVs; ++I) {
-      const auto &[A, ACond] = ExecVectors[I];
-      assert(ACond == MCDCRecord::MCDC_True);
-      for (unsigned J = 0; J < NumExecVectorsF; ++J) {
-        const auto &[B, BCond] = ExecVectors[J];
-        assert(BCond == MCDCRecord::MCDC_False);
-        // If the two vectors differ in exactly one condition, ignoring DontCare
-        // conditions, we have found an independence pair.
-        auto AB = A.getDifferences(B);
-        if (AB.count() == 1)
-          IndependencePairs.insert(
-              {AB.find_first(), std::make_pair(J + 1, I + 1)});
-      }
-    }
-  }
-
 public:
   /// Process the MC/DC Record in order to produce a result for a boolean
   /// expression. This process includes tracking the conditions that comprise
@@ -509,13 +517,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
     // Using Profile Bitmap from runtime, mark the executed test vectors.
     findExecutedTestVectors();
 
-    // Compare executed test vectors against each other to find an independence
-    // pairs for each condition.  This processing takes the most time.
-    findIndependencePairs();
-
     // Record Test vectors, executed vectors, and independence pairs.
-    return MCDCRecord(Region, std::move(ExecVectors),
-                      std::move(IndependencePairs), std::move(Folded),
+    return MCDCRecord(Region, std::move(ExecVectors), std::move(Folded),
                       std::move(PosToID), std::move(CondLoc));
   }
 };

>From f86c537e2c9224cddf10d0b05333e35bdc169361 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Fri, 27 Dec 2024 15:42:07 +0900
Subject: [PATCH 2/4] llvm-cov: Refactor CoverageSummaryInfo. NFC.

---
 llvm/tools/llvm-cov/CoverageSummaryInfo.cpp | 51 +++++++++++----------
 llvm/tools/llvm-cov/CoverageSummaryInfo.h   | 45 +++++++++---------
 2 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index ad7561d3dc62c0..5c002a694f66ae 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -16,8 +16,9 @@
 using namespace llvm;
 using namespace coverage;
 
-static void sumBranches(size_t &NumBranches, size_t &CoveredBranches,
-                        const ArrayRef<CountedRegion> &Branches) {
+static auto sumBranches(const ArrayRef<CountedRegion> &Branches) {
+  size_t NumBranches = 0;
+  size_t CoveredBranches = 0;
   for (const auto &BR : Branches) {
     if (!BR.TrueFolded) {
       // "True" Condition Branches.
@@ -32,20 +33,22 @@ static void sumBranches(size_t &NumBranches, size_t &CoveredBranches,
         ++CoveredBranches;
     }
   }
+  return BranchCoverageInfo(CoveredBranches, NumBranches);
 }
 
-static void sumBranchExpansions(size_t &NumBranches, size_t &CoveredBranches,
-                                const CoverageMapping &CM,
-                                ArrayRef<ExpansionRecord> Expansions) {
+static BranchCoverageInfo
+sumBranchExpansions(const CoverageMapping &CM,
+                    ArrayRef<ExpansionRecord> Expansions) {
+  BranchCoverageInfo BranchCoverage;
   for (const auto &Expansion : Expansions) {
     auto CE = CM.getCoverageForExpansion(Expansion);
-    sumBranches(NumBranches, CoveredBranches, CE.getBranches());
-    sumBranchExpansions(NumBranches, CoveredBranches, CM, CE.getExpansions());
+    BranchCoverage += sumBranches(CE.getBranches());
+    BranchCoverage += sumBranchExpansions(CM, CE.getExpansions());
   }
+  return BranchCoverage;
 }
 
-static std::pair<size_t, size_t>
-sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
+auto sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
   size_t NumPairs = 0, CoveredPairs = 0;
   for (const auto &Record : Records) {
     const auto NumConditions = Record.getNumConditions();
@@ -56,7 +59,7 @@ sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
         ++CoveredPairs;
     }
   }
-  return {NumPairs, CoveredPairs};
+  return MCDCCoverageInfo(CoveredPairs, NumPairs);
 }
 
 static std::pair<RegionCoverageInfo, LineCoverageInfo>
@@ -85,24 +88,27 @@ sumRegions(ArrayRef<CountedRegion> CodeRegions, const CoverageData &CD) {
           LineCoverageInfo(CoveredLines, NumLines)};
 }
 
+CoverageDataSummary::CoverageDataSummary(const CoverageData &CD,
+                                         ArrayRef<CountedRegion> CodeRegions) {
+  std::tie(RegionCoverage, LineCoverage) = sumRegions(CodeRegions, CD);
+  BranchCoverage = sumBranches(CD.getBranches());
+  MCDCCoverage = sumMCDCPairs(CD.getMCDCRecords());
+}
+
 FunctionCoverageSummary
 FunctionCoverageSummary::get(const CoverageMapping &CM,
                              const coverage::FunctionRecord &Function) {
   CoverageData CD = CM.getCoverageForFunction(Function);
-  auto [RegionCoverage, LineCoverage] = sumRegions(Function.CountedRegions, CD);
 
-  // Compute the branch coverage, including branches from expansions.
-  size_t NumBranches = 0, CoveredBranches = 0;
-  sumBranches(NumBranches, CoveredBranches, CD.getBranches());
-  sumBranchExpansions(NumBranches, CoveredBranches, CM, CD.getExpansions());
+  auto Summary =
+      FunctionCoverageSummary(Function.Name, Function.ExecutionCount);
 
-  size_t NumPairs = 0, CoveredPairs = 0;
-  std::tie(NumPairs, CoveredPairs) = sumMCDCPairs(CD.getMCDCRecords());
+  Summary += CoverageDataSummary(CD, Function.CountedRegions);
 
-  return FunctionCoverageSummary(
-      Function.Name, Function.ExecutionCount, RegionCoverage, LineCoverage,
-      BranchCoverageInfo(CoveredBranches, NumBranches),
-      MCDCCoverageInfo(CoveredPairs, NumPairs));
+  // Compute the branch coverage, including branches from expansions.
+  Summary.BranchCoverage += sumBranchExpansions(CM, CD.getExpansions());
+
+  return Summary;
 }
 
 FunctionCoverageSummary
@@ -117,8 +123,7 @@ FunctionCoverageSummary::get(const InstantiationGroup &Group,
        << Group.getColumn();
   }
 
-  FunctionCoverageSummary Summary(Name);
-  Summary.ExecutionCount = Group.getTotalExecutionCount();
+  FunctionCoverageSummary Summary(Name, Group.getTotalExecutionCount());
   Summary.RegionCoverage = Summaries[0].RegionCoverage;
   Summary.LineCoverage = Summaries[0].LineCoverage;
   Summary.BranchCoverage = Summaries[0].BranchCoverage;
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
index 64c2c8406cf3eb..d9210676c41bf3 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
@@ -223,26 +223,32 @@ class FunctionCoverageInfo {
   }
 };
 
-/// A summary of function's code coverage.
-struct FunctionCoverageSummary {
-  std::string Name;
-  uint64_t ExecutionCount;
+struct CoverageDataSummary {
   RegionCoverageInfo RegionCoverage;
   LineCoverageInfo LineCoverage;
   BranchCoverageInfo BranchCoverage;
   MCDCCoverageInfo MCDCCoverage;
 
-  FunctionCoverageSummary(const std::string &Name)
-      : Name(Name), ExecutionCount(0) {}
+  CoverageDataSummary() = default;
+  CoverageDataSummary(const coverage::CoverageData &CD,
+                      ArrayRef<coverage::CountedRegion> CodeRegions);
 
-  FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount,
-                          const RegionCoverageInfo &RegionCoverage,
-                          const LineCoverageInfo &LineCoverage,
-                          const BranchCoverageInfo &BranchCoverage,
-                          const MCDCCoverageInfo &MCDCCoverage)
-      : Name(Name), ExecutionCount(ExecutionCount),
-        RegionCoverage(RegionCoverage), LineCoverage(LineCoverage),
-        BranchCoverage(BranchCoverage), MCDCCoverage(MCDCCoverage) {}
+  auto &operator+=(const CoverageDataSummary &RHS) {
+    RegionCoverage += RHS.RegionCoverage;
+    LineCoverage += RHS.LineCoverage;
+    BranchCoverage += RHS.BranchCoverage;
+    MCDCCoverage += RHS.MCDCCoverage;
+    return *this;
+  }
+};
+
+/// A summary of function's code coverage.
+struct FunctionCoverageSummary : CoverageDataSummary {
+  std::string Name;
+  uint64_t ExecutionCount;
+
+  FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount = 0)
+      : Name(Name), ExecutionCount(ExecutionCount) {}
 
   /// Compute the code coverage summary for the given function coverage
   /// mapping record.
@@ -257,12 +263,8 @@ struct FunctionCoverageSummary {
 };
 
 /// A summary of file's code coverage.
-struct FileCoverageSummary {
+struct FileCoverageSummary : CoverageDataSummary {
   StringRef Name;
-  RegionCoverageInfo RegionCoverage;
-  LineCoverageInfo LineCoverage;
-  BranchCoverageInfo BranchCoverage;
-  MCDCCoverageInfo MCDCCoverage;
   FunctionCoverageInfo FunctionCoverage;
   FunctionCoverageInfo InstantiationCoverage;
 
@@ -270,11 +272,8 @@ struct FileCoverageSummary {
   FileCoverageSummary(StringRef Name) : Name(Name) {}
 
   FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
-    RegionCoverage += RHS.RegionCoverage;
-    LineCoverage += RHS.LineCoverage;
+    *static_cast<CoverageDataSummary *>(this) += RHS;
     FunctionCoverage += RHS.FunctionCoverage;
-    BranchCoverage += RHS.BranchCoverage;
-    MCDCCoverage += RHS.MCDCCoverage;
     InstantiationCoverage += RHS.InstantiationCoverage;
     return *this;
   }

>From 92bf1c1eeaa79a1f9a6d410744d38dd5bf342040 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Fri, 27 Dec 2024 15:44:28 +0900
Subject: [PATCH 3/4] llvm-cov: Emit RegionCoverage based on
 `CoverageData::Segments`

---
 llvm/test/tools/llvm-cov/branch-c-general.test   | 12 ++++++------
 llvm/test/tools/llvm-cov/branch-export-json.test |  2 +-
 llvm/test/tools/llvm-cov/branch-macros.test      |  6 +++---
 .../test/tools/llvm-cov/branch-noShowBranch.test | 12 ++++++------
 llvm/test/tools/llvm-cov/mcdc-general-none.test  |  6 +++---
 llvm/test/tools/llvm-cov/mcdc-general.test       |  6 +++---
 llvm/tools/llvm-cov/CoverageSummaryInfo.cpp      | 16 ++++++++--------
 llvm/tools/llvm-cov/CoverageSummaryInfo.h        |  3 +--
 8 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/llvm/test/tools/llvm-cov/branch-c-general.test b/llvm/test/tools/llvm-cov/branch-c-general.test
index 3c163bf6de45cc..9ee15ec75428e5 100644
--- a/llvm/test/tools/llvm-cov/branch-c-general.test
+++ b/llvm/test/tools/llvm-cov/branch-c-general.test
@@ -117,19 +117,19 @@
 // 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: conditionals                     22       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%        28       7  75.00%
+// REPORT-NEXT: switches                         27       4  85.19%        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%
+// REPORT-NEXT: boolean_operators                14       0 100.00%        13       0 100.00%        22       2  90.91%
+// REPORT-NEXT: boolop_loops                     15       0 100.00%        14       0 100.00%        16       2  87.50%
 // REPORT-NEXT: conditional_operator              4       2  50.00%         8       0 100.00%         4       2  50.00%
 // REPORT-NEXT: do_fallthrough                    9       0 100.00%        12       0 100.00%         6       0 100.00%
 // 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%       172      36  79.07%
+// REPORT-NEXT: TOTAL                           188      23  87.77%       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
@@ -159,7 +159,7 @@
 // HTML-INDEX: <td class='column-entry-yellow'>
 // HTML-INDEX: 96.58% (226/234)
 // HTML-INDEX: <td class='column-entry-yellow'>
-// HTML-INDEX: 87.82% (173/197)
+// HTML-INDEX: 87.77% (165/188)
 // HTML-INDEX: <td class='column-entry-red'>
 // HTML-INDEX: 79.07% (136/172)
 // HTML-INDEX: <tr class='light-row-bold'>
diff --git a/llvm/test/tools/llvm-cov/branch-export-json.test b/llvm/test/tools/llvm-cov/branch-export-json.test
index 7cf42860879827..4278482c6d870e 100644
--- a/llvm/test/tools/llvm-cov/branch-export-json.test
+++ b/llvm/test/tools/llvm-cov/branch-export-json.test
@@ -18,7 +18,7 @@
 // CHECK: 45,5,45,11,0,5,0,0,4
 // CHECK: 47,5,47,12,3,2,0,0,4
 // CHECK: 53,12,53,20,50,5,0,0,4
-// CHECK: {"count":30,"covered":26,"notcovered":4,"percent":86.666666666666671}
+// CHECK: {"count":30,"covered":26,"notcovered":4,"percent":86.6[[#]]}
 
 // Check recursive macro-expansions.
 // RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test
index e4bd14ec14f16c..b3b163f5457b03 100644
--- a/llvm/test/tools/llvm-cov/branch-macros.test
+++ b/llvm/test/tools/llvm-cov/branch-macros.test
@@ -8,8 +8,8 @@
 
 // REPORT:      Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
 // REPORT-NEXT: ---
-// REPORT-NEXT: _Z4funcii                        28       4  85.71%        18       0 100.00%        30      14  53.33%
-// REPORT-NEXT: _Z5func2ii                       13       1  92.31%         8       0 100.00%        10       2  80.00%
+// REPORT-NEXT: _Z4funcii                        12       4  66.67%        18       0 100.00%        30      14  53.33%
+// REPORT-NEXT: _Z5func2ii                        3       0 100.00%         8       0 100.00%        10       2  80.00%
 // REPORT-NEXT: main                              1       0 100.00%         6       0 100.00%         0       0   0.00%
 // REPORT-NEXT: ---
-// REPORT-NEXT: TOTAL                            42       5  88.10%        32       0 100.00%        40      16  60.00%
+// REPORT-NEXT: TOTAL                            16       4  75.00%        32       0 100.00%        40      16  60.00%
diff --git a/llvm/test/tools/llvm-cov/branch-noShowBranch.test b/llvm/test/tools/llvm-cov/branch-noShowBranch.test
index 9f3cfd55f029b5..11a9a5a665b70e 100644
--- a/llvm/test/tools/llvm-cov/branch-noShowBranch.test
+++ b/llvm/test/tools/llvm-cov/branch-noShowBranch.test
@@ -9,16 +9,16 @@
 // REPORT-NOT: Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
 // REPORT:     ---
 // REPORT-NOT: simple_loops                      8       0 100.00%         9       0 100.00%         6       0 100.00%
-// REPORT-NOT: conditionals                     24       0 100.00%        15       0 100.00%        16       2  87.50%
+// REPORT-NOT: conditionals                     22       0 100.00%        15       0 100.00%        16       2  87.50%
 // REPORT-NOT: early_exits                      20       4  80.00%        25       2  92.00%        16       6  62.50%
 // REPORT-NOT: jumps                            39      12  69.23%        48       2  95.83%        26       9  65.38%
-// REPORT-NOT: switches                         28       5  82.14%        38       4  89.47%        28       7  75.00%
+// REPORT-NOT: switches                         27       4  85.19%        38       4  89.47%        28       7  75.00%
 // REPORT-NOT: big_switch                       25       1  96.00%        32       0 100.00%        30       6  80.00%
-// REPORT-NOT: boolean_operators                16       0 100.00%        13       0 100.00%        22       2  90.91%
-// REPORT-NOT: boolop_loops                     19       0 100.00%        14       0 100.00%        16       2  87.50%
+// REPORT-NOT: boolean_operators                14       0 100.00%        13       0 100.00%        22       2  90.91%
+// REPORT-NOT: boolop_loops                     15       0 100.00%        14       0 100.00%        16       2  87.50%
 // REPORT-NOT: conditional_operator              4       2  50.00%         8       0 100.00%         4       2  50.00%
 // REPORT-NOT: do_fallthrough                    9       0 100.00%        12       0 100.00%         6       0 100.00%
 // REPORT-NOT: main                              1       0 100.00%        16       0 100.00%         0       0   0.00%
 // REPORT-NOT: c-general.c:static_func           4       0 100.00%         4       0 100.00%         2       0 100.00%
-// REPORT:     TOTAL                           197      24  87.82%       234       8  96.58%
-// REPORT-NOT: TOTAL                           197      24  87.82%       234       8  96.58%       172      36  79.07%
+// REPORT:     TOTAL                           188      23  87.77%       234       8  96.58%
+// REPORT-NOT: TOTAL                           188      23  87.77%       234       8  96.58%       172      36  79.07%
diff --git a/llvm/test/tools/llvm-cov/mcdc-general-none.test b/llvm/test/tools/llvm-cov/mcdc-general-none.test
index b57b35d49c8c11..db95314ac950ab 100644
--- a/llvm/test/tools/llvm-cov/mcdc-general-none.test
+++ b/llvm/test/tools/llvm-cov/mcdc-general-none.test
@@ -34,10 +34,10 @@
 
 //      REPORT: Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover    MC/DC Conditions    Miss   Cover
 // REPORT-NEXT: -------------------------------------------------------------------------------------------------------------------------------------------
-// REPORT-NEXT: _Z4testbbbb                      25       0 100.00%         9       0 100.00%        24       2  91.67%                  12      12   0.00%
+// REPORT-NEXT: _Z4testbbbb                      21       0 100.00%         9       0 100.00%        24       2  91.67%                  12      12   0.00%
 // REPORT-NEXT: main                              1       0 100.00%        11       0 100.00%         0       0   0.00%                   0       0   0.00%
 // REPORT-NEXT: ---
-// REPORT-NEXT: TOTAL                            26       0 100.00%        20       0 100.00%        24       2  91.67%                  12      12   0.00%
+// REPORT-NEXT: TOTAL                            22       0 100.00%        20       0 100.00%        24       2  91.67%                  12      12   0.00%
 
 // Turn off MC/DC summary.
 // RUN: llvm-cov report %S/Inputs/mcdc-general.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/mcdc-general.cpp | FileCheck %s -check-prefix=REPORT_NOMCDC
@@ -67,7 +67,7 @@
 // HTML-INDEX: <td class='column-entry-green'>
 // HTML-INDEX: 100.00% (2/2)
 // HTML-INDEX: 100.00% (20/20)
-// HTML-INDEX: 100.00% (26/26)
+// HTML-INDEX: 100.00% (22/22)
 // HTML-INDEX: 91.67% (22/24)
 // HTML-INDEX: 0.00% (0/12)
 // HTML-INDEX: Totals
diff --git a/llvm/test/tools/llvm-cov/mcdc-general.test b/llvm/test/tools/llvm-cov/mcdc-general.test
index c1e95cb2bd92ac..7ae9e180c00c29 100644
--- a/llvm/test/tools/llvm-cov/mcdc-general.test
+++ b/llvm/test/tools/llvm-cov/mcdc-general.test
@@ -100,10 +100,10 @@
 
 //      REPORT: Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover    MC/DC Conditions    Miss   Cover
 // REPORT-NEXT: -------------------------------------------------------------------------------------------------------------------------------------------
-// REPORT-NEXT: _Z4testbbbb                      25       0 100.00%         9       0 100.00%        24       2  91.67%                  12       2  83.33%
+// REPORT-NEXT: _Z4testbbbb                      21       0 100.00%         9       0 100.00%        24       2  91.67%                  12       2  83.33%
 // REPORT-NEXT: main                              1       0 100.00%        11       0 100.00%         0       0   0.00%                   0       0   0.00%
 // REPORT-NEXT: ---
-// REPORT-NEXT: TOTAL                            26       0 100.00%        20       0 100.00%        24       2  91.67%                  12       2  83.33%
+// REPORT-NEXT: TOTAL                            22       0 100.00%        20       0 100.00%        24       2  91.67%                  12       2  83.33%
 
 // Turn off MC/DC summary.
 // RUN: llvm-cov report %S/Inputs/mcdc-general.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/mcdc-general.cpp | FileCheck %s -check-prefix=REPORT_NOMCDC
@@ -133,7 +133,7 @@
 // HTML-INDEX: <td class='column-entry-green'>
 // HTML-INDEX: 100.00% (2/2)
 // HTML-INDEX: 100.00% (20/20)
-// HTML-INDEX: 100.00% (26/26)
+// HTML-INDEX: 100.00% (22/22)
 // HTML-INDEX: 91.67% (22/24)
 // HTML-INDEX: 83.33% (10/12)
 // HTML-INDEX: Totals
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index 5c002a694f66ae..86d11266ecdd7c 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -63,14 +63,15 @@ auto sumMCDCPairs(const ArrayRef<MCDCRecord> &Records) {
 }
 
 static std::pair<RegionCoverageInfo, LineCoverageInfo>
-sumRegions(ArrayRef<CountedRegion> CodeRegions, const CoverageData &CD) {
+sumRegions(const CoverageData &CD) {
   // Compute the region coverage.
   size_t NumCodeRegions = 0, CoveredRegions = 0;
-  for (auto &CR : CodeRegions) {
-    if (CR.Kind != CounterMappingRegion::CodeRegion)
+  for (auto I = CD.begin(), E = CD.end(); I != E; ++I) {
+    if (!I->IsRegionEntry || !I->HasCount || I->IsGapRegion)
       continue;
+
     ++NumCodeRegions;
-    if (CR.ExecutionCount != 0)
+    if (I->Count)
       ++CoveredRegions;
   }
 
@@ -88,9 +89,8 @@ sumRegions(ArrayRef<CountedRegion> CodeRegions, const CoverageData &CD) {
           LineCoverageInfo(CoveredLines, NumLines)};
 }
 
-CoverageDataSummary::CoverageDataSummary(const CoverageData &CD,
-                                         ArrayRef<CountedRegion> CodeRegions) {
-  std::tie(RegionCoverage, LineCoverage) = sumRegions(CodeRegions, CD);
+CoverageDataSummary::CoverageDataSummary(const CoverageData &CD) {
+  std::tie(RegionCoverage, LineCoverage) = sumRegions(CD);
   BranchCoverage = sumBranches(CD.getBranches());
   MCDCCoverage = sumMCDCPairs(CD.getMCDCRecords());
 }
@@ -103,7 +103,7 @@ FunctionCoverageSummary::get(const CoverageMapping &CM,
   auto Summary =
       FunctionCoverageSummary(Function.Name, Function.ExecutionCount);
 
-  Summary += CoverageDataSummary(CD, Function.CountedRegions);
+  Summary += CoverageDataSummary(CD);
 
   // Compute the branch coverage, including branches from expansions.
   Summary.BranchCoverage += sumBranchExpansions(CM, CD.getExpansions());
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
index d9210676c41bf3..42398ee06100e2 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
@@ -230,8 +230,7 @@ struct CoverageDataSummary {
   MCDCCoverageInfo MCDCCoverage;
 
   CoverageDataSummary() = default;
-  CoverageDataSummary(const coverage::CoverageData &CD,
-                      ArrayRef<coverage::CountedRegion> CodeRegions);
+  CoverageDataSummary(const coverage::CoverageData &CD);
 
   auto &operator+=(const CoverageDataSummary &RHS) {
     RegionCoverage += RHS.RegionCoverage;

>From 0350c1eba1c1a6b73a8d9c271a7f3c8b33202579 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Fri, 10 Jan 2025 19:24:41 +0900
Subject: [PATCH 4/4] Move mcdc-templates-merge.test from #121194

---
 .../llvm-cov/Inputs/mcdc-templates-merge.cpp  |  51 +++++++++
 .../Inputs/mcdc-templates-merge.proftext      |  73 ++++++++++++
 .../llvm-cov/Inputs/mcdc-templates-merge.yaml | 105 ++++++++++++++++++
 llvm/test/tools/llvm-cov/branch-macros.test   |   8 ++
 .../tools/llvm-cov/mcdc-templates-merge.test  |  27 +++++
 5 files changed, 264 insertions(+)
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml
 create mode 100644 llvm/test/tools/llvm-cov/mcdc-templates-merge.test

diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp
new file mode 100644
index 00000000000000..0abb308848b68a
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp
@@ -0,0 +1,51 @@
+#include <cstdio>
+
+template <typename Ty>
+bool ab(Ty a, Ty b) {
+  return (a && b);
+}
+// CHECK: [[@LINE-2]]| 4| return
+
+// CHECK: MC/DC Coverage for Decision{{[:]}}  50.00%
+// CHECK: MC/DC Coverage for Decision{{[:]}}  50.00%
+// CHECK: MC/DC Coverage for Decision{{[:]}}   0.00%
+// CHECK-NOT: MC/DC Coverage for Decision{{[:]}}
+
+// CHECK: _Z2abIbEbT_S0_{{[:]}}
+// CHECK: | | MC/DC Coverage for Decision{{[:]}}  50.00%
+
+// CHECK: _Z2abIxEbT_S0_{{[:]}}
+// CHECK: | | MC/DC Coverage for Decision{{[:]}}  50.00%
+
+// CHECK: Unexecuted instantiation{{[:]}} _Z2abIdEbT_S0_
+
+template <bool C>
+bool Cab(bool a, bool b) {
+  return (a && b && C);
+}
+// CHECK: [[@LINE-2]]| 4| return
+
+// CHECK: MC/DC Coverage for Decision{{[:]}}   0.00%
+// CHECK: MC/DC Coverage for Decision{{[:]}}  50.00%
+// CHECK-NOT: MC/DC Coverage for Decision{{[:]}}
+
+// CHECK: _Z3CabILb0EEbbb{{[:]}}
+// CHECK: | | MC/DC Coverage for Decision{{[:]}}   0.00%
+
+// CHECK: _Z3CabILb1EEbbb{{[:]}}
+// CHECK: | | MC/DC Coverage for Decision{{[:]}}  50.00%
+
+// CHECK: [[@LINE+1]]| 1|int main
+int main(int argc, char **argv) {
+  printf("%d\n", Cab<false>(false, false));
+  printf("%d\n", Cab<false>(true, true));
+  printf("%d\n", Cab<true>(true, false));
+  printf("%d\n", Cab<true>(true, true));
+  printf("%d\n", ab(false, false));
+  printf("%d\n", ab(true, true));
+  printf("%d\n", ab(1LL, 0LL));
+  printf("%d\n", ab(1LL, 1LL));
+  if (argc == 2)
+    printf("%d\n", ab(0.0, 0.0));
+  return 0;
+}
diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext
new file mode 100644
index 00000000000000..61369462b2fd46
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext
@@ -0,0 +1,73 @@
+_Z2abIbEbT_S0_
+# Func Hash:
+1550
+# Num Counters:
+3
+# Counter Values:
+2
+1
+1
+# Num Bitmap Bytes:
+$1
+# Bitmap Byte Values:
+0x5
+
+
+_Z2abIxEbT_S0_
+# Func Hash:
+1550
+# Num Counters:
+3
+# Counter Values:
+2
+2
+1
+# Num Bitmap Bytes:
+$1
+# Bitmap Byte Values:
+0x6
+
+
+_Z3CabILb0EEbbb
+# Func Hash:
+99214
+# Num Counters:
+5
+# Counter Values:
+2
+1
+0
+1
+1
+# Num Bitmap Bytes:
+$1
+# Bitmap Byte Values:
+0x5
+
+
+_Z3CabILb1EEbbb
+# Func Hash:
+99214
+# Num Counters:
+5
+# Counter Values:
+2
+1
+1
+2
+1
+# Num Bitmap Bytes:
+$1
+# Bitmap Byte Values:
+0xa
+
+
+main
+# Func Hash:
+175973464
+# Num Counters:
+2
+# Counter Values:
+1
+0
+
diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml
new file mode 100644
index 00000000000000..ba46319a63e8a4
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml
@@ -0,0 +1,105 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_GNU
+  Type:            ET_REL
+  Machine:         EM_X86_64
+  SectionHeaderStringTable: .strtab
+Sections:
+  - Name:            __llvm_covfun
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+    Content:         FAD58DE7366495DB2500000058247D0A00000000249EC986A505B62F0101010105050127210C020109070010200502000700100500110185808080080501050021
+  - Name:            '__llvm_covfun (1)'
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+    Content:         9CC3B348501DBFE8480000008E83010000000000249EC986A505B62F010103010D0D1105090901171A020201010B000C01000B0011280403000B0016300D02010300000B000C0D0010001130110603020000100011050015001630000A02000000150016
+  - Name:            '__llvm_covfun (2)'
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+    Content:         9873627177A03F8E460000008E83010000000000249EC986A505B62F010102010D0D110901171A020201010B000C01000B0011280403000B0016300D02010300000B000C0D0010001130110603020000100011050015001630090002000000150016
+  - Name:            '__llvm_covfun (3)'
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+    Content:         BF407A207503B266320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011
+  - Name:            '__llvm_covfun (4)'
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+    Content:         8A05A22CB467C37D320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011
+  - Name:            '__llvm_covfun (5)'
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+    Content:         1700192CAC8F3F26320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011
+  - Name:            __llvm_covmap
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_GNU_RETAIN ]
+    AddressAlign:    0x8
+    Content:         000000001D0000000000000006000000021A0000186D6364632D74656D706C617465732D6D657267652E637070000000
+  - Name:            __llvm_prf_names
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_GNU_RETAIN ]
+    AddressAlign:    0x1
+    Content:         51006D61696E015F5A33436162494C62304545626262015F5A33436162494C62314545626262015F5A32616249624562545F53305F015F5A32616249784562545F53305F015F5A32616249644562545F53305F
+  - Type:            SectionHeaderTable
+    Sections:
+      - Name:            .strtab
+      - Name:            __llvm_covfun
+      - Name:            '__llvm_covfun (1)'
+      - Name:            '__llvm_covfun (2)'
+      - Name:            '__llvm_covfun (3)'
+      - Name:            '__llvm_covfun (4)'
+      - Name:            '__llvm_covfun (5)'
+      - Name:            __llvm_covmap
+      - Name:            __llvm_prf_names
+      - Name:            .symtab
+Symbols:
+  - Name:            __llvm_covmap
+    Type:            STT_SECTION
+    Section:         __llvm_covmap
+  - Name:            __llvm_prf_names
+    Type:            STT_SECTION
+    Section:         __llvm_prf_names
+  - Name:            __covrec_DB956436E78DD5FAu
+    Type:            STT_OBJECT
+    Section:         __llvm_covfun
+    Binding:         STB_WEAK
+    Size:            0x41
+    Other:           [ STV_HIDDEN ]
+  - Name:            __covrec_E8BF1D5048B3C39Cu
+    Type:            STT_OBJECT
+    Section:         '__llvm_covfun (1)'
+    Binding:         STB_WEAK
+    Size:            0x64
+    Other:           [ STV_HIDDEN ]
+  - Name:            __covrec_8E3FA07771627398u
+    Type:            STT_OBJECT
+    Section:         '__llvm_covfun (2)'
+    Binding:         STB_WEAK
+    Size:            0x62
+    Other:           [ STV_HIDDEN ]
+  - Name:            __covrec_66B20375207A40BFu
+    Type:            STT_OBJECT
+    Section:         '__llvm_covfun (3)'
+    Binding:         STB_WEAK
+    Size:            0x4E
+    Other:           [ STV_HIDDEN ]
+  - Name:            __covrec_7DC367B42CA2058Au
+    Type:            STT_OBJECT
+    Section:         '__llvm_covfun (4)'
+    Binding:         STB_WEAK
+    Size:            0x4E
+    Other:           [ STV_HIDDEN ]
+  - Name:            __covrec_263F8FAC2C190017u
+    Type:            STT_OBJECT
+    Section:         '__llvm_covfun (5)'
+    Binding:         STB_WEAK
+    Size:            0x4E
+    Other:           [ STV_HIDDEN ]
+...
diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test
index 2ff4355def2349..b60da157810cf4 100644
--- a/llvm/test/tools/llvm-cov/branch-macros.test
+++ b/llvm/test/tools/llvm-cov/branch-macros.test
@@ -1,5 +1,7 @@
 // RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
 // RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=999
+// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=FILE
+
 // RUN: llvm-cov show --binary-counters --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=1
 // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT
 
@@ -14,3 +16,9 @@
 // REPORT-NEXT: main                              1       0 100.00%         6       0 100.00%         0       0   0.00%
 // REPORT-NEXT: ---
 // REPORT-NEXT: TOTAL                            16       4  75.00%        32       0 100.00%        40      16  60.00%
+
+// FILE:      Filename          Regions Missed Regions  Cover   Functions Missed Functions Executed      Lines  Missed Lines    Cover   Branches Missed Branches Cover
+// FILE-NEXT: ---
+// FILE-NEXT: branch-macros.cpp      16              4  75.00%          3                0  100.00%         32             0   100.00%        40              16 60.00%
+// FILE-NEXT: ---
+// FILE-NEXT: TOTAL                  16              4  75.00%          3                0  100.00%         32             0   100.00%        40              16 60.00%
diff --git a/llvm/test/tools/llvm-cov/mcdc-templates-merge.test b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test
new file mode 100644
index 00000000000000..cacd3b6bc6d844
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test
@@ -0,0 +1,27 @@
+# Test `merge-instantiations=merge/any/all`
+
+RUN: yaml2obj %S/Inputs/mcdc-templates-merge.yaml -o %t.o
+RUN: llvm-profdata merge %S/Inputs/mcdc-templates-merge.proftext -o %t.profdata
+
+RUN: llvm-cov show --show-mcdc -show-instantiations=true %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/mcdc-templates-merge.cpp
+
+RUN: llvm-cov report --show-mcdc-summary %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s
+
+REPORT: mcdc-templates-merge.cpp
+
+# Regions
+CHECK:      10  1  90.00%
+
+# Functions
+CHECK:       3  0 100.00%
+
+# Lines
+CHECK:      19  1  94.74%
+
+# Branches
+CHECK:      11  3  72.73%
+
+# MC/DC Conditions
+CHECK:       4  2  50.00%
+
+REPORT: TOTAL



More information about the llvm-commits mailing list