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

generated code of inline assembly modifier 'P' with -fPIE is different between gcc and clang #60096

Open
bysui opened this issue Jan 17, 2023 · 3 comments

Comments

@bysui
Copy link

bysui commented Jan 17, 2023

GCC version: 9.3.0
Clang version: 15.0.7

The output assembly code of following code is different between gcc and clang with -c -O2 -fPIE:

#include <stdio.h>

#pragma GCC visibility push(hidden)

#define current(var) ({\
	typeof(var) pfo_ret__;\
	asm("movq %%gs:%P1, %0\n"\
	    : "=r"(pfo_ret__)\
	    : "p" (&(var))\
	);\
	pfo_ret__;\
})


struct foo {
	int field1;
	int field2;
};

extern struct foo a;

int test ()
{
	int total;

	total = current(a).field1 + current(a).field2;
	printf ("total: %d\n", total);

	return 0;
}

The expected assembly code should be like this:

movq %gs:a(%rip), %rax

Clang could generate right code but gcc generates absolute reference:

movq %gs:a, %rax

It seems that modifier 'P' is not compatible with PIE in gcc, so I try to use modifier 'a'
and it can generate right code. But modifier 'a' leads to compilation error in clang.
image

My question is why the generated code of modifier 'P' is different between gcc and clang?
Which one is right?

Thanks.

@nickdesaulniers
Copy link
Member

@bysui
Copy link
Author

bysui commented May 25, 2023

Documentation: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86-Operand-Modifiers

Hi Nick,

I had looked up the documentation before. Regarding the 'P' modifier, it states that it "Prints the raw symbol name if used for a constant". If I understand correctly, it should generate an absolute reference. I have tested it by compiling with both -fPIE and -fno-PIE, but it seems to have no impact. So, GCC always generates an absolute reference, whereas CLANG always generates a RIP-relative reference, regardless of -fPIE being used or not.

I think the documentation is not clear enough for the user.

Additionally, I was unable to find an explanation for the 'a' modifier, even in the source code of gcc. Furthermore, it appears that the 'p' modifier is also not supported in CLANG.

I think that the documentation may be insufficient for users to fully understand the behavior of these modifiers. :(

@llvmbot
Copy link
Collaborator

llvmbot commented Sep 28, 2023

@llvm/issue-subscribers-backend-x86

GCC version: 9.3.0 Clang version: 15.0.7

The output assembly code of following code is different between gcc and clang with -c -O2 -fPIE:

#include &lt;stdio.h&gt;

#pragma GCC visibility push(hidden)

#define current(var) ({\
	typeof(var) pfo_ret__;\
	asm("movq %%gs:%P1, %0\n"\
	    : "=r"(pfo_ret__)\
	    : "p" (&amp;(var))\
	);\
	pfo_ret__;\
})


struct foo {
	int field1;
	int field2;
};

extern struct foo a;

int test ()
{
	int total;

	total = current(a).field1 + current(a).field2;
	printf ("total: %d\n", total);

	return 0;
}

The expected assembly code should be like this:

movq %gs:a(%rip), %rax

Clang could generate right code but gcc generates absolute reference:

movq %gs:a, %rax

It seems that modifier 'P' is not compatible with PIE in gcc, so I try to use modifier 'a'
and it can generate right code. But modifier 'a' leads to compilation error in clang.
image

My question is why the generated code of modifier 'P' is different between gcc and clang?
Which one is right?

Thanks.

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

4 participants