<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/126370>126370</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Clang generates invalid code with `-finline-functions`
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
igormunkin
</td>
</tr>
</table>
<pre>
We faced an issue with function inlining optimizations in scope of this PR: tarantool/msgpuck#41. You can find the reproducer we reduced from the original issue with @Gerold103 [here](https://github.com/tarantool/msgpuck/pull/41#issuecomment-2638311985), but let's proceed with the one, provided by @Gumix [here](https://github.com/tarantool/msgpuck/pull/41#issuecomment-2638329954). TBH, we don't know, whether both issues have the same root cause, but the latter reproducer is smaller at least.
So, we have the source file `a.c` with the following contents:
```cpp
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
static uint64_t unused_func(uint8_t type, const char *data) {
switch (type) {
case 8: {
struct cast { uint8_t val; };
return ((struct cast *)data)->val;
}
case 16: {
struct cast { uint16_t val; };
uint16_t val = ((struct cast *)data)->val;
return __builtin_bswap16(val);
}
case 32: {
struct cast { uint32_t val; };
uint32_t val = ((struct cast *)data)->val;
return __builtin_bswap32(val);
}
case 64: {
struct cast { uint64_t val; };
uint64_t val = ((struct cast *)data)->val;
return __builtin_bswap64(val);
}
}
abort();
}
//__attribute__((noinline))
static void store_0_to_buf(void *buf) {
struct cast { uint8_t val; };
((struct cast *)buf)->val = 0;
}
int main() {
char buf_a[2][8];
char buf_b[2][8];
store_0_to_buf(buf_a[0]);
store_0_to_buf(buf_a[1]);
store_0_to_buf(buf_b[0]);
store_0_to_buf(buf_b[1]);
for (int ai = 0; ai < 2; ++ai) {
for (int bi = 0; bi < 2; ++bi) {
const char *data_a = buf_a[ai];
const char *data_b = buf_b[bi];
struct cast { uint8_t val; };
uint8_t ca = ((struct cast *) data_a)->val;
uint8_t cb = ((struct cast *) data_b)->val;
if (ca != cb) {
uint64_t a = unused_func(ca, data_a + 1);
uint64_t b = unused_func(cb, data_b + 1);
printf("??? %d\n", a > b);
}
printf("ok ");
}
}
}
```
Here is the version of the Clang I use on my machine:
```
$ clang++ --version
clang version 19.1.7
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm/19/bin
Configuration file: /etc/clang/x86_64-pc-linux-gnu-clang++.cfg
$ clang --version
clang version 19.1.7
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm/19/bin
Configuration file: /etc/clang/x86_64-pc-linux-gnu-clang.cfg
```
When building the source code above with the different optimization flags, I get the following results:
```
$ clang++ a.c -O2
clang++: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
$ ./a.out
$ clang++ a.c -O2 -fno-inline-functions
clang++: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
$ ./a.out
ok ok ok ok
$ clang++ a.c -O3
clang++: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
$ ./a.out
ok ok ok ok
$ # --- mind using clang instead of clang++ below ---
$ clang a.c -O2
$ ./a.out
ok ok ok ok
$ clang a.c -O2 -fno-inline-functions
$ ./a.out
ok ok ok ok
$ clang a.c -O3
$ ./a.out
ok ok ok ok
```
As you can see, there is nothing printed when `a.c` is compiled via `clang++` with `-O2`. Running the binary, compiled with `-fsanitize=undefined`, works fine and yields no UB issues.
Here are the links to the resulting asm, generated by godbolt:
* `-O2`: https://godbolt.org/z/ov839cs8x
* `-O2 -fno-inline-functions`: https://godbolt.org/z/43r1P1fPz
* `-O3`: https://godbolt.org/z/jdKKdfh6c
I agree with assumptions, got by inlining zero-initializing routine, and, ergo, agree with the code, emitted for `-O3`. But I don't get how empty `main` can be generated for the loop, that calls the functions with side effects.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzcWF9v4zgO_zTqC5HAlvPPD3lI2s3tYB9usLeHwT0FkkzH2tqSIcnJtJ_-QNn51yadDrAH3N0gmCYS-fOPNEmREt7rnUFcsumaTZ8eRBcq65Z6Z13TmWdtHqQtXpbfEEqhsABhQHvfIRx0qKDsjAraGtCm1kabHdg26Ea_Clr1oA14ZVsEW0KotIevv7NsBUE4YYK1NeObxu_aTj0znk3SMfzLdqCEgVKbAkKF4LB1tugUOjjQL_paQOlsE7et0zttRH1Jik2Sv6GzdZEmGbDpukKHbPrE-KIKofUsWzG-YXyz06Hq5FjZhvHNTUqbtqtpYZIynsUnKNs0aMKIz7JFlqb5Ysp4zvgjyC5AjYHxuYfWWYVY9GwiS4Mk0zq71wUWIF8iya7R3_-jBHmeTyeM52P4Y_0rMTggFNYwPg_wbOwhLlUYKnQgbah6L3qoxB4jcS8aBGdtACU6j0dDaasWIaC7fD_ag29EXaMDQc4QPoxZsmLJ6h92ePgZ2HZOIZS6RmCzRIwVmyVnh5W2ru2B4klZE9CE6JRkxWZJ_1FtSz95po2quwKBZY8-FNqOK5b9cmur1vLunjbhtJesfBBBK-i0CbPJNkBnOo_FlmKd8QUtL7YBwksb_aGs8QFUJRwwvipEEIznwObrCJb7gw6qAsYXvcLFlhIeYUH5cFoiheA6Rf72gdbh-Ly9qFm2BjZ_YtlZ2mHonCF4xhdXqnzFeD7QGbHsl15_UJw_XVBIZ5_hkM7ukrjcBpY9_TSdkx3brex0HbTZSn8QbTpjfEGSPL_DPeOf4Z7xD7kft_9S7hn_EffZ5DPcYwje537c_ku5zyYfcD99EdK6EB95lBp2hvK13YoQnJZdwO22p2ZsPCgwFs38nGt7qwvwwTrcJttgt7IriQGtMr6Kvy5z6idS5I5HesjBIdF3yRsbtAnQCG16Ay-yljJdduVWsOmaU9merhf0J3srIO8IvLPziJbEQyD_sWD6GUH5WUT5HpFkS0sVbUF-EPrkov77I_Doab5mfC30lYOuVeWFqnynKt-pkgPfVdStiCBH84W-dOddJXlSIgvlDaWfq7VDxpGAEh_mG_Skb6fcJYz8BIy8C6NLUiUuPCUcJW9487JO9KyvzzMl6BQ7epmvIb3K-ncY8haGPGHIDzBap00oo7WcZZv-A4xPCzZ9NLTIHyPHX0DeADgVoHdg9hmi9rXKm4LV_39sIPow_xUdUt9CPccenadWNraqCI-1MDv4Ap2n_g2aF2iEqqh2XXcisdxNQJF4H9QwGg1YLFnF9RN2mo_T8Zwlqz-E22Gg-v99MdvOJqNWjWptuu-jnelov3IoCmhsgTVJtdbr7yxZfTE-UItVPGkXTw--6bxjfFNrSf_Xe-oV05zxjdT0_EdrSr3rXGzIY781qGFQjG8G2psbLEYXJo1Vubs09P_KxKNx16HxrUIDdCoW1IZe9KzKFghC2j2e-9VClyU6NOFq_oGyFjtPQf0FdhjedLYOfVe_a2xvhJMYKxj9nR893a-SiQfhaOaKE5VDEQiV8blifA7atF0A4YeFqMLn1O3TsAaPAzZ5nwjG4UxiJfbaxk6-wNahEgELmlBG386_qYz2JMeMb8TYduE-aRiVxo76Q390nBb9f7cp9hlOn7uWZfA_ZwTjGYxGI2hotu58nK5i6mrjA6WiLa8MlVjbA2lcZf45Gj_rtx_GwgdAN3AyeKsC8d8NBtcZvfLwMlwveBy8PNR_Y0NF_oiHCk3u9FrOc6n2oGzT6hoL2GtBO5ev_ji5sllCnpklY_i9M-ZYN6Q2wr30s-IAchIvvTA66Fdk2VNnCiy1wYIY07xs3bMHWgFhCnjRWBdEFf65Hgb18cUpJlw_WdfaPHsIdrg9oRpDRIRvCHOHBl2MIvkCO1tIW4ehAvHV2QAK4Td3Eb3s2Dqqpa-Mb-x-keXKL75fKd95yZ-DnGQu_ZqWX18vIbNPKv9Z_PZbUVYz1TvlC4idw6FGC--7pu2pkBdsIPtPl1av6IizDlrU-jUWZ9sF3d_aCFPQH3S7eItxgUoeVkPCYqMDuTW2vkfaY1h3Ab6c7lzoEKjsAbBpwwuJxQFjlsSYlHjxdggmvk1r2z5SBbWGdd33KifH9kS8LhCwLFEFP6bIfyiWWZFnuXjAZTrP8oRnfDJ9qJa5zGWSzdN8nqjZJMvTfFHwRIl5JspUzuWDXvKETxOeLNJJkkymY1EolU-KZFrOSzWbcjZJsBG6HtNBTO5_iLG4TPksmycPtZBY-3ibyPmQJDQEPbglKYxkt_NsktTaB3-GCDrUuOxbrqMTPGizF7Uu-hP3nDI3guuhc_Xyg8uzoWmIDFpn_0QVGN_0SUTNRM99v-T_DgAA___37lEA">