| Issue |
60992
|
| Summary |
[clang15] problem about function call optimization without "-fno-inline-functions" option
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
Air111
|
Hi,
I got interesting result on this testcase:
```c
#include <stdint.h>
int32_t a;
static uint32_t safe_mod_func_uint32_t_u_u(uint32_t ui1, uint32_t ui2) {
return (ui2 == 0)? (ui1): (ui1 % ui2);
}
int64_t b(void) {
int32_t *c = &a;
uint64_t d = 9934966375;
e:
d--;
if (safe_mod_func_uint32_t_u_u(6, a)) {
if (d)
goto e;
*c = 0;
}
return 0;
}
int main(void) {
b();
}
```
Command line:
```console
$ clang-15 -v
Ubuntu clang version 15.0.7
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
$ clang-15 -Os small.c -o small1
$ time ./small1
real 0m3.490s
user 0m3.490s
sys 0m0.000s
$ clang-15 -fno-inline-functions -Os small.c -o small2
$ time ./small2
real 0m0.001s
user 0m0.001s
sys 0m0.000s
```
I found the reason why small1 runs much slower through the assembly code:
```console
$ objdump -d small1
...
000000000000112c <b>:
112c: 48 b9 99 71 d4 af fd movabs $0xfffffffdafd47199,%rcx
1133: ff ff ff
1136: 8b 35 f0 2e 00 00 mov 0x2ef0(%rip),%esi # 402c <a>
113c: 85 f6 test %esi,%esi
113e: 74 0d je 114d <b+0x21>
1140: b8 06 00 00 00 mov $0x6,%eax
1145: 31 d2 xor %edx,%edx
1147: f7 f6 div %esi
1149: 85 d2 test %edx,%edx
114b: 74 0f je 115c <b+0x30>
114d: 48 ff c1 inc %rcx
1150: 75 ea jne 113c <b+0x10>
1152: c7 05 d0 2e 00 00 00 movl $0x0,0x2ed0(%rip) # 402c <a>
1159: 00 00 00
115c: 31 c0 xor %eax,%eax
115e: c3 retq
...
$ objdump -d small2
...
000000000000112c <b>:
112c: 50 push %rax
112d: 8b 3d f9 2e 00 00 mov 0x2ef9(%rip),%edi # 402c <a>
1133: e8 12 00 00 00 callq 114a <safe_mod_func_uint32_t_u_u>
1138: 85 c0 test %eax,%eax
113a: 74 0a je 1146 <b+0x1a>
113c: c7 05 e6 2e 00 00 00 movl $0x0,0x2ee6(%rip) # 402c <a>
1143: 00 00 00
1146: 31 c0 xor %eax,%eax
1148: 59 pop %rcx
1149: c3 retq
...
```
In small2, Clang thinks `safe_mod_func_uint32_t_u_u` is a pure function and "a" is a constant, so function b only calls `safe_mod_func_uint32_t_u_u` once. But in small1, with "-finline-functions", the code of function `safe_mod_func_uint32_t_u_u` is executed many times.
I have on idea why Clang did not treat the function call as a constant with "-finline-functions". Hope to get some help.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs