Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLVM 19.1.6 [[clang::preserve_most]] targeting x86-32 can clobbers result register #122648

Open
Nick-Kooij opened this issue Jan 12, 2025 · 1 comment

Comments

@Nick-Kooij
Copy link

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:

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Jan 12, 2025
@EugeneZelenko EugeneZelenko added clang:codegen and removed clang Clang issues not falling into any other category labels Jan 13, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 13, 2025

@llvm/issue-subscribers-clang-codegen

Author: None (Nick-Kooij)

Consider the following function, attributed with `[[clang::preserve_most]]`:
extern void bar( int* );

[[clang::preserve_most]] [[clang::noinline]] int foo( int x ) {
    bar( &amp;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:

&lt;int foo(int)&gt;:
               	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	 &lt;L0&gt;
		IMAGE_REL_I386_REL32	?bar@@<!-- -->YAXPAH@<!-- -->Z
&lt;L0&gt;:
               	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:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants