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

Reply via email to