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

    <tr>
        <th>Summary</th>
        <td>
            [LTO] Dynamic initializer incorrectly optimized out
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    Since 601645c3b70e2a17d18779a3a51b8bc9ecdc9aa6, CC @rnk, the following testcase fails:

main.cpp:
```c++
int DoIt() { return 0; }
inline int Unused0 = DoIt();
int GetUnused();
int main(int, char **) { return GetUnused(); }
```

lib.cpp:
```c++
int DoIt();
inline int Unused0 = DoIt();
int GetUnused() { return Unused0; }
```

stub.c:
```c
void __cxa_guard_acquire(void) {}
void __cxa_guard_release(void) {}
void __gxx_personality_seh0(void) {}
void __cxa_guard_abort(void) {}
void _Unwind_Resume(void) {}
void __main(void) {}
```

To reproduce:
```console
$ clang -target x86_64-w64-mingw32 -c stub.c
$ clang -target x86_64-w64-mingw32 -c main.cpp -mguard=cf -flto=thin
$ clang -target x86_64-w64-mingw32 -c lib.cpp -mguard=cf -flto=thin
$ lld-link lib.o main.o stub.o -out:out.exe -entry:main
lld-link: error: undefined symbol: __cxx_global_var_init
>>> referenced by out.exe.lto.lib.obj
```

The reason for this is visible, if we inspect the output of the LTO compile:
```
$ lld-link lib.o main.o stub.o -out:out.exe -entry:main -lldemit:asm
$ cat out.exe.lto.main.s | grep -A1 -B1 __cxx_global_var_init
        .section        .gfids$y,"dr"
        .symidx __cxx_global_var_init
        .section        .giats$y,"dr"
--
        .addrsig
        .addrsig_sym __cxx_global_var_init
        .addrsig_sym Unused0
```

So due to the `-mguard=cf`, we end up keeping a reference to `__cxx_global_var_init` in the `.gfids$y` section - but the LTO optimization itself has decided to optimize out the `__cxx_global_var_init` function entirely.

It seems like the exact ordering of object files is crucial here; if I swap the order of `lib.o` and `main.o` in this example, then `out.exe.lto.main.s` does retain the `__cxx_global_var_init` function, but `out.exe.lto.lto.s` has lost the function instead.

This was originally reported downstream at https://github.com/mstorsjo/llvm-mingw/issues/457.

Debugging what really happens during the LTO compilation is somewhat finicky; if I grab the LTO IR with `-lldemit:llvm -out:lto.bc` and try to compile that with `llc`, I get different results as well. (In that case, I end up with an undefined `GetUnused()` function.)

As the referenced commit 601645c3b70e2a17d18779a3a51b8bc9ecdc9aa6 was NFCI, no functional changes intended, but we do have functional changes here, I think it would be reasonable to revert the commit.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV1tv6rgW_jXmZQkUHCDwwEMLp0eVRmekmT3PyLFXkrXr2Dm2U2B-_ZFNuHSX3e7qjJRWxF6Xb90-O8J7qg3ims0fGefOvDDO2Xw7En1orFu3Pljnv9tRadVx_ScZibDIpovZXOZlkSEX00JNl0WxErmYT8tlKVcolVwJsWB8A5sNsFmWzG4gNAiV1druydQQ0AcpPEIlSHuWP7Bsy7LhfyvITGTXXZcX2emRjD_GJ62SCbC1z4HxJeMrYMUjOAy9M5Cx_BFYsT3LaTIIUfwv03tUGbB8e6PK8huL_8ZwkrqzF4ExviQTYkSyEQ4Yf0jPG__vbVzRXGK5jVhT-eWAb5D9H_Hdwh60P4frQ19O5D206f3VkoLdTh7Eru6FUzsh_9uTQ8aXcWvwenHxTtyhRuE_Ea8Ph12HzlsjNIXjzmOT_aoDUVoXPhT-y-zJqN0f6Pv2EyBDU9yTuJu8bxYcds6qXuKdFFrjrcZhlc9AamFqGAfhagxwWC52i9l4v5iNWzL1PucwljDU40s65yGDcZuSwvKtrGBc6WBZvg0Nma_ZG1r4V8xprcaazEvSsSck9hSEhbHtA8sfbB8meEAYownuyPJECsOwDOosfwB0zrr4ozcKKzKowB_b0uq4Fkt-2NXalkLvXoXbkaEwwMj_dXrAYYUOjUQF5REGtxMd7CShK79_VMoGwaHw1kBlHYSGPJCHV_JUaowcQRXs42j6DmVIHGj70PUBbJXefvv2O0jbdqTv9MI_kDEYa62wpSggfHtTUhHeBJtMemDFBmqHHYwfpjB-nH6Yw2w18SgDWRN_1hUpz_jsyPiGca5cPEyugseW1IFlqy8YJBHuGxyPrwpCKeepfrew88f2M_S3omfy-3m1_7SgeoRgU-XYIrtt9SjLN7HYaBT0HbwgdvGkE9cOi6pskd0HtciAzNnyTTIXGQw5gTGUfbi0je0CtfS3SFsUPOoKGuFBoSSFKjobRFLTnU3_1HvVm5MbNIEc6uPkNvjnAB6x9aDpBZMtPAgZwDqFLsZpK7Dl99jlFWlMcyBdL0loaNBhPFSogmfwe9GdBiFqRjW2yFJbRxDCqPh-avBLTshHb213mqnQoIlC79s3KiiLPh5o4prNT0OOVmNqfzAa_5LNmFZt_SmHlzyR8QGFmrxlBPKwFx6so5qM0PoY2d66gAqU3RsfHIoWRIAmhC7dfPgT4081hSaSuG0ZfzpfvBh_0vq1PdEs40_kfY-e8afZvHjjdotlX9exDPtGhMhJ0XEjug6NB9WnCr3lm6FvPHjbYtKqyJB8OV4qVTtRXpSe_4A9hSa1_ZVSIroz_8RslfJcxOCOsQMHboMQHZwNaC2HcXmGeKAoqtKEROC-18GD8LBHrSfA-PLZnLRluhJEnWHCkjlhbqifLbIfr143VZ7E95ukPfgU3c0BIG3bUvjlO24q9H-eNs8RlrEXR0LHu6Gp4xSYgEZFNKcO2yMoC414xXvSaVBSiPHAfAEKsLe9VlCezxlR6kQjDl_RnfrxBHoyUutcrfKVGOF6WvBilk-nRTZq1liUWaGmq7ycTafzCuflfF4UIp-WqlwUGR_Rmmd8lq14ka3mqzybyGpeKFxwzFS5LPKKzTJsBelJLPfEunqUGnE9nWY85yMtStR--IgwuIe0O3xKuHXq4LKvPZtlmnzwVzOBgk5fH799-53Nt7A9GtGShDifJDT9jQ7ISOscyqCPFz5TkdBGvdPrD4YoejkPUOdspKbbERrAv675_wIAAP__LDMVqQ">