| Issue |
108879
|
| Summary |
[clang 18] x86-64 miscompile with boolean conditions
|
| Labels |
clang
|
| Assignees |
|
| Reporter |
liamwhite
|
The following C++ code ([minimized from from this report](https://gitlab.com/inkscape/inkscape/-/merge_requests/6696))
```cpp
struct ToolBase {};
struct CanvasEvent {};
struct Desktop {
ToolBase* tool;
};
bool start_root_handler(ToolBase* tool, const CanvasEvent& event);
bool tool_handler(const CanvasEvent& event, Desktop* desktop) {
if (auto const tool = desktop->tool) {
return start_root_handler(tool, event);
}
return false;
}
```
produces broken compiled output with clang 18.1.x ([compiler explorer](https://godbolt.org/z/dco6hfs8f)):
```x86asm
tool_handler(CanvasEvent const&, Desktop*):
push rbx
mov rbx, qword ptr [rsi]
test rbx, rbx
je .LBB0_1
mov rax, rdi
mov rdi, rbx
mov rsi, rax
call start_root_handler(ToolBase*, CanvasEvent const&)@PLT
jmp .LBB0_3
.LBB0_1:
.LBB0_3:
test rbx, rbx
setne cl
and cl, al
mov eax, ecx
pop rbx
ret
```
The issue occurs on these lines
```x86asm
setne cl
and cl, al
mov eax, ecx
```
Only the low byte of the c register is clobbered by `setne cl`. However, the optimizer seemingly assumes that the entire `c` register has been clobbered, and ends up moving garbage/undefined 32-bit data in the `mov eax, ecx` line.
```
(gdb) si
(gdb) p $ecx
$5 = 2069502208
(gdb) p $eax
$6 = 2069502208
(gdb) p $cl
$7 = 0
(gdb) p $al
$8 = 0
```
This results in the function returning a nonsense non-boolean value which breaks the functions that call it.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs