Never use .lcomm on platforms where it does not accept an alignment

argument.  Instead, use a pair of .local and .comm directives.

This avoids spurious differences between binaries built by the
integrated assembler vs. those built by the external assembler,
since the external assembler may impose alignment requirements
on .lcomm symbols where the integrated assembler does not.

llvm-svn: 168704
This commit is contained in:
Ulrich Weigand 2012-11-27 16:11:16 +00:00
parent b0448cd52a
commit e5f9405842
3 changed files with 12 additions and 5 deletions

View File

@ -308,8 +308,13 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return;
}
if (Align == 1 ||
MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {
// Use .lcomm only if it supports user-specified alignment.
// Otherwise, while it would still be correct to use .lcomm in some
// cases (e.g. when Align == 1), the external assembler might enfore
// some -unknown- default alignment behavior, which could cause
// spurious differences between external and integrated assembler.
// Prefer to simply fall back to .local / .comm in this case.
if (MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {
// .lcomm _foo, 42
OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align);
return;

View File

@ -10,7 +10,8 @@
@STRIDE = internal global i32 8
; ASM: .type array00,%object @ @array00
; ASM-NEXT: .lcomm array00,80
; ASM-NEXT: .local array00
; ASM-NEXT: .comm array00,80,1
; ASM-NEXT: .type _MergedGlobals,%object @ @_MergedGlobals

View File

@ -4,8 +4,9 @@
@c = internal global i8 0, align 1
@x = internal global i32 0, align 4
; CHECK: .lcomm c,1
; .lcomm doesn't support alignment.
; .lcomm doesn't support alignment, so we always use .local/.comm.
; CHECK: .local c
; CHECK-NEXT: .comm c,1,1
; CHECK: .local x
; CHECK-NEXT: .comm x,4,4