Issue |
144816
|
Summary |
clang generates incorrect code with -O2
|
Labels |
clang
|
Assignees |
|
Reporter |
Evenedric
|
The code below delivers different results from clang, depending on the level of optimization. Correct behavior is:
```
> g++ mytest.cc -Wall && ./a.out
n=1 r=0.000000
```
Incorrect behavior is:
```
> g++ -O2 mytest.cc -Wall && ./a.out
n=2 r=7.000000
```
(I'm looking at the value of `n`, it should be returned as 1). Behavior is the same when running with UBSAN and ASAN (and no violations observed). I don't _think_ the code is a victim of undefined behavior.
Other information:
```
> g++ -v
Apple clang version 17.0.0 (clang-1700.0.13.3)
Target: arm64-apple-darwin24.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
```
Note that following combination of things are necessary to reproduce the bad behavior, so this is a minimal example:
* Use `std::min()`
* Use `atan()`
* Don't initialize `r` in `main()`
* `printf()` the value of `r`.
The code is below.
```cpp
#include <math.h>
#include <stdio.h>
#include <algorithm>
int Foo(double *r) {
double a = std::min(2.0, atan(1) + 10); // == 2
if (a > 3) { // Should be false
*r = 5 + a;
return 2;
}
return 1;
}
int main() {
double r;
int n = Foo(&r);
printf("n=%d r=%f \n", n, r);
return 0;
}
```
Examination of the disassembled `-O2` code shows the optimizer inlined `Foo()` and chose the incorrect path:
```
_main:
0000053c sub sp, sp, #0x20 ; Adjust stack frame
00000540 stp x29, x30, [sp, #0x10] ; Save x29, x30
00000544 fmov d0, #1.00000000 ; d0 = 1.0
00000548 bl 0x10000058c ; symbol stub for: _atan ; d0 = atan(1.0)
0000054c fmov d1, #10.00000000 ; d1 = 10.0
00000550 fadd d0, d0, d1 ; d0 = atan(1.0) + 10.0
00000554 fmov d1, #2.00000000 ; d1 = 2.0
00000558 fminnm d0, d0, d1 ; d0 = min(atan(1.0) + 10.0, 2.0)
0000055c fmov d1, #5.00000000 ; d1 = 5.0
00000560 fadd d0, d0, d1 ; d0 = min(atan(1.0) + 10.0, 2.0) + 5.0
00000564 mov w8, #0x2 ; w8 = 2
00000568 str x8, [sp] ; store the printf argument '2'
0000056c str d0, [sp, #0x8] ; store the printf argument d0
00000570 adrp x0, 0 ; 0x100000000
00000574 add x0, x0, #0x5a4 ; x0 = literal pool for: "n=%d r=%f \n"
00000578 bl 0x100000598 ; symbol stub for: _printf ; Call printf
0000057c mov w0, #0x0
00000580 ldp x29, x30, [sp, #0x10]
00000584 add sp, sp, #0x20
00000588 ret
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs