[llvm-commits] [PATCH/RFC] Only use .lcomm if it supports alignment

Ulrich Weigand Ulrich.Weigand at de.ibm.com
Tue Nov 27 06:05:33 PST 2012


Hello,

on some platforms, the assembler supports a ".lcomm" directive to create a
local common (BSS) variable.  Unfortunately, this is implemented
differently across platforms: on some platforms, .lcomm supports a
user-specified alignment argument, on others it does not.  Where the
alignment argument is not supported (or not specified), the assembler will
assume a default alignment requirement derived from the variable size in a
platform-specific manner.

When using an external assembler, LLVM will always use .lcomm on platforms
where the alignment argument is supported (and always pass what LLVM
considers the variable's alignment).  However, on platforms where the
alignment argument is not supported (which unfortunately include ELF), it
is not valid in general to use .lcomm.  LLVM currently does so for
variables that have no alignment requirement.  This is clearly always
*correct*, no matter what the platform-specific details of .lcomm alignment
are.

However, if we want LLVM to always produce the same binary with the
integrated assembler as it does with the external one, this is still a
problem: if LLVM considers the variable to have no alignment requirement,
the integrated assembler will enforce no alignment requirement, but simply
place the variable at the next free address.  However, the external
assembler *may* implement *some* alignment requirement it has derived (in a
platform-specific manner) from the .lcomm size.  This means it may actually
add padding bytes before the variable -- resulting in a different binary.

Now one way to fix this would be for the LLVM to exactly emulate the
alignment behaviour of .lcomm on each given target, and only use .lcomm if
the variable's actual alignment requirement matches what the .lcomm
algorithm would derive.  However, this seems tedious and error-prone, and
probably not actually very useful.  Note that in cases where .lcomm cannot
be used, LLVM already falls back to issuing a pair of .local and .comm
directives, which always allows to specify the precise alignment
requirement, and has otherwise the same effect as .lcomm.

Thus, it would appear to me that the simplest fix would be to simply never
use .lcomm and always fall back to .local / .comm on targets where .lcomm
does not support an alignment argument.  The attached patch implements
this.  (Note that two tests need to be modified to check for the new
behaviour instead of the old one.)

Tested on powerpc64-linux with no regression; with this patch, the
integrated and the external assembler produce 100% identical data sections
(.data, .bss, .rodata ...) on all objects in test-suite.  (There are still
differences in .eh_frame and debug sections.)

OK to commit?

Bye,
Ulrich

(See attached file: diff-llvm-lcomm)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: diff-llvm-lcomm
Type: application/octet-stream
Size: 2030 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121127/c0e8e871/attachment.obj>


More information about the llvm-commits mailing list