[llvm-branch-commits] [clang] [llvm] [Coverage][Single] Enable Branch coverage for SwitchStmt (PR #113112)

NAKAMURA Takumi via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Dec 21 09:13:26 PST 2024


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

>From ec05cc37e1177f06c9a44a1e39dadc9306cc5c68 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Mon, 21 Oct 2024 08:09:31 +0900
Subject: [PATCH 1/2] [Coverage][Single] Enable Branch coverage for SwitchStmt

---
 clang/lib/CodeGen/CGStmt.cpp                  | 12 ++++++++++
 clang/lib/CodeGen/CoverageMappingGen.cpp      | 22 ++++++++++---------
 .../CoverageMapping/single-byte-counters.cpp  | 13 ++++++-----
 3 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index dbc1ce9bf993cd..80fe5cf183de16 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2259,6 +2259,18 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
 
   ConditionScope.ForceCleanup();
 
+  // Close the last case (or DefaultBlock).
+  EmitBranch(SwitchExit.getBlock());
+
+  // Insert a False Counter if SwitchStmt doesn't have DefaultStmt.
+  if (getIsCounterPair(S.getCond()).second) {
+    auto *ImplicitDefaultBlock = createBasicBlock("sw.false");
+    EmitBlock(ImplicitDefaultBlock);
+    incrementProfileCounter(true, S.getCond());
+    Builder.CreateBr(SwitchInsn->getDefaultDest());
+    SwitchInsn->setDefaultDest(ImplicitDefaultBlock);
+  }
+
   // Emit continuation.
   EmitBlock(SwitchExit.getBlock(), true);
   incrementProfileCounter(&S);
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index a331d5bc68286b..c5fdf23299e4e9 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -958,6 +958,14 @@ struct CounterCoverageMappingBuilder
     return {ExecCnt, SkipCnt};
   }
 
+  Counter getSwitchImplicitDefaultCounter(const Stmt *Cond, Counter ParentCount,
+                                          Counter CaseCountSum) {
+    return (
+        llvm::EnableSingleByteCoverage
+            ? Counter::getCounter(CounterMap[Cond].second = NextCounterNum++)
+            : subtractCounters(ParentCount, CaseCountSum));
+  }
+
   bool IsCounterEqual(Counter OutCount, Counter ParentCount) {
     if (OutCount == ParentCount)
       return true;
@@ -1885,7 +1893,7 @@ struct CounterCoverageMappingBuilder
       propagateCounts(Counter::getZero(), Body);
     BreakContinue BC = BreakContinueStack.pop_back_val();
 
-    if (!BreakContinueStack.empty() && !llvm::EnableSingleByteCoverage)
+    if (!BreakContinueStack.empty())
       BreakContinueStack.back().ContinueCount = addCounters(
           BreakContinueStack.back().ContinueCount, BC.ContinueCount);
 
@@ -1900,11 +1908,6 @@ struct CounterCoverageMappingBuilder
     MostRecentLocation = getStart(S);
     handleFileExit(ExitLoc);
 
-    // When single byte coverage mode is enabled, do not create branch region by
-    // early returning.
-    if (llvm::EnableSingleByteCoverage)
-      return;
-
     // Create a Branch Region around each Case. Subtract the case's
     // counter from the Parent counter to track the "False" branch count.
     Counter CaseCountSum;
@@ -1920,7 +1923,8 @@ struct CounterCoverageMappingBuilder
     // 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 DefaultCount = subtractCounters(ParentCount, CaseCountSum);
+      Counter DefaultCount = getSwitchImplicitDefaultCounter(
+          S->getCond(), ParentCount, CaseCountSum);
       createBranchRegion(S->getCond(), Counter::getZero(), DefaultCount);
     }
   }
@@ -1929,9 +1933,7 @@ struct CounterCoverageMappingBuilder
     extendRegion(S);
 
     SourceMappingRegion &Parent = getRegion();
-    Counter Count = llvm::EnableSingleByteCoverage
-                        ? getRegionCounter(S)
-                        : addCounters(Parent.getCounter(), getRegionCounter(S));
+    Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
 
     // Reuse the existing region if it starts at our label. This is typical of
     // the first case in a switch.
diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp
index d20b695bc2636a..464fa370d86f09 100644
--- a/clang/test/CoverageMapping/single-byte-counters.cpp
+++ b/clang/test/CoverageMapping/single-byte-counters.cpp
@@ -34,19 +34,22 @@ int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]]
 }
 
 // CHECK-NEXT: testSwitch
-int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = [[C30:#0]]
+int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+20]]:2 = [[C30:#0]]
   int result;
   switch (x) {
-                        // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+10]]:15 = 0
-  case 1:               // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = [[C31:#2]]
+                        // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+13]]:15 = 0
+  case 1:               // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = [[C31:#2]]
+                        // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = [[C31]], 0
     result = 1;
     break;
                         // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0
-  case 2:               // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = [[C32:#3]]
+  case 2:               // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = [[C32:#3]]
+                        // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = [[C32]], 0
     result = 2;
     break;
                         // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0
-  default:              // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:15 = [[C3D:#4]]
+  default:              // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:15 = [[C3D:#4]]
+                        // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = [[C3D]], 0
     result = 0;
   }
                         // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C3E:#1]]

>From cce771fa5512089c69ddfad30f2267124f3f46b5 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Thu, 21 Nov 2024 00:18:39 +0900
Subject: [PATCH 2/2] Update test

---
 .../Inputs/branch-c-general-single.proftext   |  6 ++--
 .../Inputs/branch-c-general-single.yaml       | 12 +++----
 .../tools/llvm-cov/Inputs/branch-c-general.c  | 32 +++++++++----------
 3 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext
index ea8c6f9bc634ed..b92df1d6a38a32 100644
--- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext
@@ -192,7 +192,7 @@ jumps
 # Func Hash:
 15051420506203462683
 # Num Counters:
-38
+39
 # Counter Values:
 1
 1
@@ -232,6 +232,7 @@ jumps
 1
 1
 1
+0
 
 main
 # Func Hash:
@@ -263,7 +264,7 @@ switches
 # Func Hash:
 43242458792028222
 # Num Counters:
-29
+30
 # Counter Values:
 1
 1
@@ -294,4 +295,5 @@ switches
 1
 0
 0
+0
 
diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml
index 9d23dcb67ad2ac..6bbf80e14941d6 100644
--- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml
@@ -26,17 +26,17 @@ Sections:
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001
+    Content:         55947829059F255ED50100001B9C495D3463E1D04C551E9517F40F4F0101004A013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090420009901010D000E00001006918080800869010501112069000005000B0001120185808080086D01050112206D000005000B00011301858080800871010501112071000005000B5D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001
   - Name:            '__llvm_covfun (4)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001
+    Content:         7129CA3C268292BF8B0100003E688383C9A099004C551E9517F40F4F010103292D516151613D016C112502100201011C000217028A80808008090103010A2009000003000A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F2021000005000B21010B000C25000D008E8080800825000E00101001010015030105100F202D000005000B03010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F2039000005000B39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F2045000005000B45010B000C49000D008E8080800849000E00104D0107080F200075000F001000001203918080800855010702112055000007001355010D000E59000F00908080800859001000125D0109001151010802858080800810010100010B0105020F2061000005000C0B010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001
   - Name:            '__llvm_covfun (5)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
     AddressAlign:    0x8
-    Content:         3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001
+    Content:         3F4D1C6E6087417B65010000D6FF56B8865A69B64C551E9517F40F4F010101212538019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C2019000005001219010B000C1D000D008E808080081D000E00101001010015030105150C2025000005001203010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C2031000005002031010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C203D00000500133D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C2049000005002149010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C2055000005002755010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C2061000005000C61010B000C65000D008E8080800865000E0010690107000C1003010001
   - Name:            '__llvm_covfun (6)'
     Type:            SHT_PROGBITS
     Flags:           [ SHF_GNU_RETAIN ]
@@ -124,19 +124,19 @@ Symbols:
     Type:            STT_OBJECT
     Section:         '__llvm_covfun (3)'
     Binding:         STB_WEAK
-    Size:            0x1D4
+    Size:            0x1F1
     Other:           [ STV_HIDDEN ]
   - Name:            __covrec_BF9282263CCA2971u
     Type:            STT_OBJECT
     Section:         '__llvm_covfun (4)'
     Binding:         STB_WEAK
-    Size:            0x169
+    Size:            0x1A7
     Other:           [ STV_HIDDEN ]
   - Name:            __covrec_7B4187606E1C4D3Fu
     Type:            STT_OBJECT
     Section:         '__llvm_covfun (5)'
     Binding:         STB_WEAK
-    Size:            0x14E
+    Size:            0x181
     Other:           [ STV_HIDDEN ]
   - Name:            __covrec_58A39A89A88AA459u
     Type:            STT_OBJECT
diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c
index 5ea9ecb42b0ed1..5fb4ad3c364dca 100644
--- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c
@@ -86,11 +86,11 @@ void jumps() {                  // CHECK: @LINE|{{.*}}jumps()
   while (i < 3) {               // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1]
   loop2:
     switch (i) {
-    case 0:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
+    case 0:                     // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded]
       goto first;
-    case 1:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
+    case 1:                     // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded]
       goto second;
-    case 2:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
+    case 2:                     // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded]
       goto third;
     }
   }
@@ -110,30 +110,30 @@ void switches() {               // CHECK: @LINE|{{.*}}switches()
 
   // No cases -> no weights
   switch (weights[0]) {
-  default:                      // BRCOV: Branch ([[@LINE]]:3): [True: 1, Folded]
+  default:                      // CHECK: Branch ([[@LINE]]:3): [True: 1, Folded]
     break;
   }
                                 // BRCOV: Branch ([[@LINE+1]]:63): [True: [[C15:15|1]], False: 0]
   for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) {
     switch (i[weights]) {
-    case 1:                     // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
+    case 1:                     // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1]
       // fallthrough
-    case 2:                     // BRCOV: Branch ([[@LINE]]:5): [True: [[C2]], Folded]
+    case 2:                     // CHECK: Branch ([[@LINE]]:5): [True: [[C2:2|1]], Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 1]
       break;
-    case 3:                     // BRCOV: Branch ([[@LINE]]:5): [True: [[C3:3|1]], Folded]
+    case 3:                     // CHECK: Branch ([[@LINE]]:5): [True: [[C3:3|1]], Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[C3]], False: 0]
       continue;
-    case 4:                     // BRCOV: Branch ([[@LINE]]:5): [True: [[C4:4|1]], Folded]
+    case 4:                     // CHECK: Branch ([[@LINE]]:5): [True: [[C4:4|1]], Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[C4]], False: 0]
       switch (i) {
-      case 6 ... 9:             // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], Folded]
+      case 6 ... 9:             // CHECK: Branch ([[@LINE]]:7): [True: [[C4]], Folded]
         if (i) {}               // BRCOV: Branch ([[@LINE]]:13): [True: [[C4]], False: 0]
         continue;
       }
 
-    default:                    // BRCOV: Branch ([[@LINE]]:5): [True: [[C5:5|1]], Folded]
+    default:                    // CHECK: Branch ([[@LINE]]:5): [True: [[C5:5|1]], Folded]
       if (i == len - 1)         // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: [[C4]]]
         return;
     }
@@ -147,21 +147,21 @@ void switches() {               // CHECK: @LINE|{{.*}}switches()
 void big_switch() {             // CHECK: @LINE|{{.*}}big_switch()
   for (int i = 0; i < 32; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[C32:32|1]], False: 1]
     switch (1 << i) {
-    case (1 << 0):              // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
+    case (1 << 0):              // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1]
       // fallthrough
-    case (1 << 1):              // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
+    case (1 << 1):              // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 1]
       break;
-    case (1 << 2) ... (1 << 12):// BRCOV: Branch ([[@LINE]]:5): [True: [[C11:11|1]], Folded]
+    case (1 << 2) ... (1 << 12):// CHECK: Branch ([[@LINE]]:5): [True: [[C11:11|1]], Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[C11]], False: 0]
       break;
       // The branch for the large case range above appears after the case body.
 
-    case (1 << 13):             // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded]
+    case (1 << 13):             // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0]
       break;
-    case (1 << 14) ... (1 << 28)://BRCOV: Branch ([[@LINE]]:5): [True: [[C15]], Folded]
+    case (1 << 14) ... (1 << 28)://CHECK: Branch ([[@LINE]]:5): [True: [[C15:15|1]], Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[C15]], False: 0]
       break;
     // The branch for the large case range above appears after the case body.
@@ -169,7 +169,7 @@ void big_switch() {             // CHECK: @LINE|{{.*}}big_switch()
     case (1 << 29) ... ((1 << 29) + 1):
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0]
       break;
-    default:                    // BRCOV: Branch ([[@LINE]]:5): [True: [[C2]], Folded]
+    default:                    // CHECK: Branch ([[@LINE]]:5): [True: [[C2:2|1]], Folded]
       if (i) {}                 // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 0]
       break;
     }



More information about the llvm-branch-commits mailing list