<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/116521>116521</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [coverage] Inconsistent subview grouping when the function only has one decision
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            tools:llvm-cov
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          whentojump
      </td>
    </tr>
</table>

<pre>
    ## Effect

When the function contains multiple decisions, branches from different instantiations are separated by the delimiter:

```text
 1|       |static inline __attribute__((always_inline))
    2|      2|int foo(int a, int b) {
    3|      2|    if (a) return a;
 ------------------
  |  Branch (3:9): [True: 0, False: 1]
 ------------------
  |  Branch (3:9): [True: 1, False: 0]
 ------------------
    4|      1|    if (b) return b;
 ------------------
  |  Branch (4:9): [True: 1, False: 0]
 ------------------
  |  Branch (4:9): [True: 0, False: 0]
 ------------------
    5|      0|    return 0;
    6| 1|}
```

When comment out the second decision and only keep the first one, branches from different instantiations are wrongly put into one group (no delimiter):

```text
    1|       |static inline __attribute__((always_inline))
    2|      2|int foo(int a, int b) {
 3|      2|    if (a) return a;
  ------------------
  |  Branch (3:9): [True: 0, False: 1]
  |  Branch (3:9): [True: 1, False: 0]
 ------------------
    4|       |    // if (b) return b;
    5|      1| return 0;
    6|      2|}
```

How to reproduce:

```shell
cat > header.h << 'EOF'
static inline __attribute__((always_inline))
int foo(int a, int b) {
    if (a) return a;
    if (b) return b;
    return 0;
}
EOF
cat > lib.c << 'EOF'
#include "header.h"

int bar() {
    foo(0, 2);
 return 0;
}
EOF
cat > main.c << 'EOF'
#include "header.h"

int bar();

int main(void) {
    foo(1, 3);
 bar();
    return 0;
}
EOF
clang -fprofile-instr-generate -fcoverage-mapping lib.c main.c -o test
./test
llvm-profdata merge default.profraw -o default.profdata
llvm-cov show -show-branches=count -instr-profile default.profdata test
```

## Cause

https://github.com/llvm/llvm-project/blob/5bb9465d35914e9833c4fe9278a855a4cd75c7af/llvm/tools/llvm-cov/CodeCoverage.cpp#L337-L345

Here grouping purely relies on line number and the order within `Branches`.

- When there're multiple decisions in a function, `Branches` elements are ordered like

    ```python
    [ # instantiation 1
      Line1, Line2, ...,
      # instantiation 2
 Line1, Line2, ...,
      # instantiation 3
      Line1, Line2, ...,
    ]
    ```

    Branches from different instantiations, although having the same line number, is separated by other decisions in the function.

- Otherwise, there's no separation which leads to the incorrect grouping.

    ```python
    [ # instantiation 1
 Line1,
      # instantiation 2
      Line1,
      # instantiation 3
      Line1,
    ]
    ```

cc @evodius96 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV11vozgX_jXOzVEQ2BCSi1y06UTvK400NyvtZWXMIXjG2Mg2yfbfr-xAQtrpTFt1d6MIjD8en-d8-Zg7Jw8acUuKe1I8LPjgW2O3pxa1N9-Hrl9Upn7aEsoIZfClaVB4kj6Q9O78_LNFDb5FaAYtvDQahNGeS-2gG5SXvUKoUUgnjXaE7qCyXIsWHTTWdFDLpkGL2oPUznPtJQ8gDrhFcNhzyz3WUD3FPWpUspMeLWF3cyHIKj3_Pf41SgcZKXdw_pFy5zz3UoDUSmqEx0fuvZXV4PHxkdA1oWuuTvzJPZ4nELoJ_zMQANALVmhJ7aExhtB1aPFAKjQqQjdAyvvrMnazLLxlA2GvMNOiH6wGTti0YvniN0HF1fdRcWE9I-wuCsjugBT3f9gBQzMNkuy5cvErI8XDJwFnN8DpW4AB8gv57IZ8NSNffYB8_mkyvg04_Qj54kI-HVsj4_TKGABWYTCoh5QPzzz5RYwJ03UhTszgYyw4FEbXl9gCrmswWj3BD8T-HJHSOg8muPO7wu5kjT6oJ-iHMOxNgICDNUMf1KTNLAyjtn4XiTMX-K-C8Z2R-M-F4r8TcTC2CN0Tuv914N14a7TT66560eCv_fV_5gTegMXemnoQ-JqPuBaVOvcJ7oGwL9Air9EmLRC2I2wHhJZfvu0JLc_TPu45b07av3aM32SxnwX6RVeByA1ZJatEvMKUUCa1UEONQCid1EIonWsyMuA2Un9G48w1-iGN_jWNvUO-jkv9iQJed7yMhR0IXR-NrF9hECOB3TB4CfhWvSuuD7BsemsaqXAZcp9dHlBjqDJg2QhzRMsPuOx430t9GC006mFpwKMbs1pC6P76pdSxWwbYmnsOHdpDKFYaPiifhG7LT2H5vCvMnC0W5giuNSdYhudySteEPQgzaA-jsKPoL5Bmkv00JMf6bccHh_P-1vvehfiMmeIgfTtUiTAdofsg1vgK234PhR_dV8pUhO6Lqtrkq6JmxSbLcbNmTOQNbmi55uui4Lmoy0KUvLnieGOUm_CEORK635kad6PKE9H3hLKvjJXLrywvbvIJ2vEACjbpB4vqCSwqiQ6MhpgL9NBVaOMpGM4-Y2u0cJK-lRrIKr2f9LlKkzn0EqYC1iKhpcWfVK0gNfBLfRv88RYQUGE4ms-nZ9wZa1Dyx42mYz6eTNM_-dbo2UBxD8E-N6cxZNcJAF-lxhgMoUFDI0kSQnfzOS8hxmj84Gr2PgFmx9yM63Ml3L-pEgn4XPnWDIcWWn4Mlo9lD-9wbvGYyN3tVcEEc97ab35DeeYA38Lsk3SxTJocwYE2E2jQxKmVogWFvHbhaAtwUgtjLQp_cc3kk-w9afptpr0xzgfs-R77CQEkT_Foajm4zQoW9ZbVG7bhC9xmJcvWGU036aLdUlY2WVoUgrNSpLiiacmwFjnb5Gm1ZuVCbmlK8yzLypQWeZEmeVataMnWaVNX9XrFwz4dlyoJCSMx9rCQzg24zbJVQbOF4hUqF2-tlJ5zC7u75hYa7rJ2Gzuq4eBInirpvLuieelVvPVOSZ8UD_B_LYx20vngkG6ojhJP18xzenHXjQV3y10skSeHWwxWbd-dWCO7kCBHgsct_TsAAP__biZbDg">