-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Open
Labels
clang:codegenIR generation bugs: mangling, exceptions, etc.IR generation bugs: mangling, exceptions, etc.miscompilation
Description
Consider the following function, attributed with [[clang::preserve_most]]:
extern void bar( int* );
[[clang::preserve_most]] [[clang::noinline]] int foo( int x ) {
bar( &x );
return x * x;
}
When targeting x86-32, this emits the following incorrect code, which saves and restores the result register (EAX) breaking the return value:
<int foo(int)>:
push edx
push ecx
push eax ; RESULT REGISTER SAVED
push edi
push esi
push edx
push ecx
push ebp
push edi
push esi
push ebp
push esp
push ebx
lea eax, [esp + 0x38]
push eax
call <L0>
IMAGE_REL_I386_REL32 ?bar@@YAXPAH@Z
<L0>:
add esp, 0x4
mov eax, dword ptr [esp + 0x38]
imul eax, eax
pop ebx
pop esp
pop ebp
pop esi
pop edi
pop ebp
pop ecx
pop edx
pop esi
pop edi
pop eax ; RESULT CLOBBERED
pop ecx
pop edx
ret
The following attached project, should print "64" and exit. x86-32 builds instead print the arbitrary value of whatever was in the EAX register when bar was called.
Note: I'm using LLVM through clang-cl under Visual Studio, bug I suspect the issue is more fundamental than the compiler driver.
Steps to reproduce:
- Obtained LLVM-19.1.6-win64.exe from the official Assets.
- Install on Windows 11 with Visual Studio 2022 17.12.3
- Must build a x86-32 target
- x64 targets link and run properly
- PreserveMostBug.zip
Metadata
Metadata
Assignees
Labels
clang:codegenIR generation bugs: mangling, exceptions, etc.IR generation bugs: mangling, exceptions, etc.miscompilation