<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">The given example has undefined
      behavior; C++ ODR says that inline functions are required to have
      the same definition in every translation unit.  (You can avoid
      this problem by making the function in question "static inline".) 
      You're lucky that the only consequence you're seeing is that the
      coverage output is wrong; it could very easily lead to a crash or
      memory corruption instead.<br>
      <br>
      -Eli<br>
      <br>
      On 11/29/2017 4:28 AM, Serge Preis via cfe-dev wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:160621511958524@webcorp01h.yandex-team.ru">
      <div>Hello Vedant,</div>
      <div> </div>
      <div>I tried to look into this with Sam and hope my initial
        analysys will help.</div>
      <div> </div>
      <div>It seems to me that we face some kind of profile counter
        aliasing:</div>
      <div> </div>
      <div>On slightly different example I see the following in .ll
        files:</div>
      <div>** In inlined code same counters are incremented in 2
        differently inlined codes (dpending on define like in the code
        Sam provided). They look like:</div>
      <div> </div>
      <div>
        <div>
          <div>  %pgocount.i = load i64, i64* getelementptr inbounds ([2
            x i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri, i64
            0, i64 0), align 8, !dbg !23</div>
          <div>  %1 = add i64 %pgocount.i, 1, !dbg !23</div>
          <div>  store i64 %1, i64* getelementptr inbounds ([2 x i64],
            [2 x i64]* @__profc__Z22inline_foo_from_headeri, i64 0, i64
            0), align 8, !dbg !23 <<<<< Counter #0</div>
          <div>...</div>
          <div>if.then.i:                                        ; preds
            = %entry</div>
          <div>  %pgocount8.i = load i64, i64* getelementptr inbounds
            ([2 x i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri,
            i64 0, i64 1), align 8, !dbg !27</div>
          <div>  %2 = add i64 %pgocount8.i, 1, !dbg !27</div>
          <div>  store i64 %2, i64* getelementptr inbounds ([2 x i64],
            [2 x i64]* @__profc__Z22inline_foo_from_headeri, i64 0, i64
            1), align 8, !dbg !27 <<<<< Counter #1</div>
        </div>
      </div>
      <div> </div>
      <div>The 2nd counter naturally belongs to different code paths in
        different inlining destination files.</div>
      <div> </div>
      <div> </div>
      <div>** The counters structure looks like following in both files:</div>
      <div>@__profd__Z22inline_foo_from_headeri = linkonce_odr hidden
        global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64
        -3479956896993626287, i64 10, i64* getelementptr inbounds ([2 x
        i64], [2 x i64]* @__profc__Z22inline_foo_from_headeri, i32 0,
        i32 0), i8* bitcast (i32 (i32)* @_Z22inline_foo_from_headeri to
        i8*), i8* null, i32 2, [2 x i16] zeroinitializer }, section
        "__llvm_prf_data", comdat($__profv__Z22inline_foo_from_headeri),
        align 8</div>
      <div> </div>
      <div>So the counters are definitely shared between inlined
        instances, This looks reasonable.</div>
      <div> </div>
      <div>** The __llvm_coverage_mapping structures are indeed
        different, but refere to same counters:</div>
      <div> </div>
      <div>
        <div>
          <div>@__llvm_coverage_mapping = internal constant { { i32,
            i32, i32, i32 }, [2 x <{ i64, i32, i64 }>], [192 x i8]
            } { { i32, i32, i32, i32 } { i32 2, i32 148, i32 44, i32 1
            }, [2 x <{ i64, i32, i64 }>] [<{ i64, i32, i64
            }> <{ i64 -2070989330109684161, i32 9, i64 0 }>,
            <{ i64, i32, i64 }> <{ i64 -3479956896993626287,
            i32 31, i64 10 }>], [192 x i8]
c"\02D/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/lib1/lib1.cppM/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h</div>
          <div>\01\00\00\01</div>
          <div>\01\03\15\02\02\</div>
          <div> </div>
          <div>01\01\ << This is about
/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h</div>
          <div>01\01\05\ << One expression(counter #0, #1) ---
            There was an else branch in one of my cases</div>
          <div> </div>
          <div>05\</div>
          <div>01\03\2B\0E\02\ << This is for counter #0</div>
          <div>01\03\09\00\0A\ << This is for counter #0</div>
          <div>05\01\09\00\14\ << This is for counter #1</div>
          <div>02\02\09\00\14\ << This is subtraction for counters
            #0-#1 according to expression above</div>
          <div>10\01\02\04\02\ << This is skipped region because
            of #ifdef</div>
          <div>00\00\00\00" }, section "__llvm_covmap", align 8</div>
        </div>
      </div>
      <div> </div>
      <div>And</div>
      <div> </div>
      <div>
        <div>
          <div>@__llvm_coverage_mapping = internal constant { { i32,
            i32, i32, i32 }, [2 x <{ i64, i32, i64 }>], [184 x i8]
            } { { i32, i32, i32, i32 } { i32 2, i32 148, i32 36, i32 1
            }, [2 x <{ i64, i32, i64 }>] [<{ i64, i32, i64
            }> <{ i64 7422656158144208762, i32 9, i64 0 }>,
            <{ i64, i32, i64 }> <{ i64 -3479956896993626287,
            i32 24, i64 10 }>], [184 x i8]
c"\02D/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/lib2/lib2.cppM/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h</div>
          <div>\01\00\00\01\</div>
          <div>01\03\15\02\02\</div>
          <div> </div>
          <div>01\01\ << This is about
/xxxx/xxxxxx/xxx/xxxx/xxxxxxxxx/test/compilation_flags/header/single_header.h</div>
          <div>00\ << no expressions in this case</div>
          <div>04\</div>
          <div>01\03\2B\0E\02\ << This is for counter #0</div>
          <div>10\02\02\05\02\ << This is skipped region because
            of #ifdef</div>
          <div>01\06\09\00\0A\ << This is for counter #0</div>
          <div>05\01\09\00\14\ << This is for counter #1</div>
          <div>00\00\00" }, section "__llvm_covmap", align 8</div>
        </div>
      </div>
      <div> </div>
      <div> </div>
      <div>***</div>
      <div>So now we have 2 different coverage mappings referring same
        counters, but attributing them to different paths in the code.
        This doesn't seem right to me and I don't see any possibility
        for this case to work properly after linking. I am not even sure
        that this situation is ever fixable: in order to assign
        different counters instrumentation pass should know a lot about
        #ifdef-ed out code, while it is not even a part of AST. Or
        alternatively counters for inlined code shouldn't be shared
        among inlining sites, but this would have created a lot of
        troubles for accounting and extremely infalted counter
        structures.</div>
      <div> </div>
      <div>What worries me here is why some mapping regions are ignored
        in this case: they all are in the final binary, but excluded
        from accounting by some reason. Even if they stayed coverage
        would be incorrect but in some better way. It would mistakely
        cover #ifdef-ed out code as visited, but this is definitely
        better than additionally reporting some visited line as
        unvisited.</div>
      <div> </div>
      <div> </div>
      <div>Thank you,</div>
      <div>-- </div>
      <div>Serge Preis</div>
      <div> </div>
      <div> </div>
      <div> </div>
      <div> </div>
      <div>29.11.2017, 02:46, "Vedant Kumar via cfe-dev"
        <a class="moz-txt-link-rfc2396E" href="mailto:cfe-dev@lists.llvm.org"><cfe-dev@lists.llvm.org></a>:</div>
      <blockquote type="cite">
        <div>Hi,
          <div> </div>
          <div>Thanks for the report, I'll take a look.</div>
          <div> </div>
          <div>vedant</div>
          <div> 
            <div>
              <blockquote type="cite">
                <div>On Nov 28, 2017, at 5:15 AM, Sam Toliman via
                  cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org"
                    moz-do-not-send="true">cfe-dev@lists.llvm.org</a>>
                  wrote:</div>
                 
                <div>
                  <div>
                    <div>Hi all,</div>
                    <div> </div>
                    <div>I have faced unexpected coverage results for
                      inline function with conditional #ifdef</div>
                    <div> </div>
                    <div>// -- header.h</div>
                    <div>#pragma once<br>
                      <br>
                      inline int bar(int x) {<br>
                          int y = 10;<br>
                      #ifdef IE<br>
                          if (x)<br>
                              y *= 2;<br>
                      #else<br>
                          y -= 5;<br>
                      #endif<br>
                          return x * y;<br>
                      }</div>
                    <div> </div>
                    <div>// -- lib1.cpp</div>
                    <div>#include "header.h"<br>
                      <br>
                      int lib1_foo(int x) {<br>
                          return bar(x) + x;<br>
                      }</div>
                    <div> </div>
                    <div>// -- main.cpp</div>
                    <div>#include <iostream><br>
                      #include "header.h"<br>
                      <br>
                      extern int lib1_foo(int);<br>
                      <br>
                      int main_foo(int x) {<br>
                          return bar(x) + x;<br>
                      }<br>
                      <br>
                      int main(int c, char**) {<br>
                          std::cout << lib1_foo(c) << " "
                      << main_foo(c) << std::endl;<br>
                          return 0;<br>
                      }</div>
                    <div> </div>
                    <div>clang++ -fprofile-instr-generate
                      -fcoverage-mapping -O2 -c -g lib1.cpp -o lib1.o <strong>-DIE</strong><br>
                      clang++ -fprofile-instr-generate
                      -fcoverage-mapping -O2 -c -g main.cpp -o main.o<br>
                      clang++ -fprofile-instr-generate
                      -fcoverage-mapping -O2 -g main.o lib1.o -o bin<br>
                      ./bin<br>
                      llvm-profdata merge -o merged.prof default.profraw<br>
                      llvm-cov export -instr-profile merged.prof -object
                      bin</div>
                    <div> </div>
                    <div>Output of the program will be "21 6"</div>
                    <div>However, segments for header.h will be:</div>
                    <div>[3,23,2,1,1],[5,2,0,0,1],[8,2,2,1,0],[12,2,0,0,0]
                      ("y -= 5;" was performed twice)</div>
                    <div>Looks like coverage wasn't able to connect
                      source code with counters properly.</div>
                    <div> </div>
                    -Sam</div>
                  _______________________________________________<br>
                  cfe-dev mailing list<br>
                  <a href="mailto:cfe-dev@lists.llvm.org"
                    moz-do-not-send="true">cfe-dev@lists.llvm.org</a><br>
                  <a
                    href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev"
                    moz-do-not-send="true">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></div>
              </blockquote>
            </div>
          </div>
        </div>
        ,
        <p>_______________________________________________<br>
          cfe-dev mailing list<br>
          <a href="mailto:cfe-dev@lists.llvm.org" moz-do-not-send="true">cfe-dev@lists.llvm.org</a><br>
          <a
            href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev"
            moz-do-not-send="true">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></p>
      </blockquote>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
cfe-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
    </blockquote>
    <p><br>
    </p>
    <pre class="moz-signature" cols="72">-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project</pre>
  </body>
</html>