This is an archive of the discontinued LLVM Phabricator instance.

[AsmPrinter] GlobalAlias with non-zero size and public linkage ends up with wrong size, PR38794
Needs ReviewPublic

Authored by daphnediane on Sep 4 2018, 8:24 AM.

Details

Summary

Fix PR38794

The size of global aliases were not showing up correctly in object files. The updated logic checks if the alias is at an offset from the global object or has a size and that size is smaller than the global object. This expands the logic in rL244752.

Diff Detail

Event Timeline

daphnediane created this revision.Sep 4 2018, 8:24 AM
daphnediane retitled this revision from [CODEGEN] GlobalAlias with non-zero size and public linkage ends up with wrong size, PR#38794 to [AsmPrinter] GlobalAlias with non-zero size and public linkage ends up with wrong size, PR38794.Sep 5 2018, 8:36 AM
daphnediane edited the summary of this revision. (Show Details)

The reason for the default of not emitting a size (which ends up having the effect of the alias having the same size as the aliasee) is for compatibility with gcc where if you have

int var1[10] = {1};
extern int var2 __attribute__((alias("var1")));

you end up with var2 being a symbol with the same size as var1, even though it's a smaller type.

So I think checking for the size being smaller is incorrect, or rather it would mean we would be inconsistent with gcc which we generally want to avoid unless there's a good reason, but the change to emit the size when the alias has an offset (i.e. the change in how we decide BaseObject) looks OK. It does make me wonder though if perhaps it would be better to explicitly distinguish at the IR level between alias as "this name is another name for that other thing", which we want for the alias variable attribute and so don't want to emit a size; and "this name refers to a subpart of that other thing", which we want for aliases generated by GlobalMerge and so do want to emit a size.

The reason for the default of not emitting a size (which ends up having the effect of the alias having the same size as the aliasee) is for compatibility with gcc where if you have

int var1[10] = {1};
extern int var2 __attribute__((alias("var1")));

you end up with var2 being a symbol with the same size as var1, even though it's a smaller type.

So I think checking for the size being smaller is incorrect, or rather it would mean we would be inconsistent with gcc which we generally want to avoid unless there's a good reason, but the change to emit the size when the alias has an offset (i.e. the change in how we decide BaseObject) looks OK. It does make me wonder though if perhaps it would be better to explicitly distinguish at the IR level between alias as "this name is another name for that other thing", which we want for the alias variable attribute and so don't want to emit a size; and "this name refers to a subpart of that other thing", which we want for aliases generated by GlobalMerge and so do want to emit a size.

Note I'm using LLVM IR for a different language not C/C++ and need to be able to generate partial symbols of different sizes. The programming language I'm porting has a concept of combined segments where some parts of the segments are public and that the layout between them is well defined within a single module but only visible by symbol name to external modules.

It does make me wonder though if perhaps it would be better to explicitly distinguish at the IR level between alias as "this name is another name for that other thing", which we want for the alias variable attribute and so don't want to emit a size; and "this name refers to a subpart of that other thing", which we want for aliases generated by GlobalMerge and so do want to emit a size.

Was considering trying this using attributes, but it looks like while GlobalValues contain an AttributeSet, GlobalAliases do not. I wonder if the best fix would just allow any sized global alias to emit sizes and have clang change how it makes such aliases so that the external symbol is unsized possibly with a command line flag to allow the sizes to match. It's interesting that the gcc documentation only has alias listed as supporting functions and not variables. https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes and https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html. Other attributes that are common have references back to function attributes in the variable attribute section.

john.brawn resigned from this revision.May 12 2020, 6:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 12 2020, 6:40 AM