aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h9
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp56
-rw-r--r--test/CodeGen/X86/alignment.ll29
-rw-r--r--test/CodeGen/X86/unaligned-load.ll4
-rw-r--r--test/FrontendC/cstring-align.c5
5 files changed, 70 insertions, 33 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index b5c287ae90..243ddbb5da 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -204,12 +204,8 @@ namespace llvm {
/// EmitAlignment - Emit an alignment directive to the specified power of
/// two boundary. For example, if you pass in 3 here, you will get an 8
/// byte alignment. If a global value is specified, and if that global has
- /// an explicit alignment requested, it will unconditionally override the
- /// alignment request.
- ///
- /// The algorithm is:
- /// Align = NumBits;
- /// if (GV && GV->hasalignment) Align = GV->getAlignment();
+ /// an explicit alignment requested, it will override the alignment request
+ /// if required for correctness.
///
void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const;
@@ -218,7 +214,6 @@ namespace llvm {
/// it if appropriate.
void EmitBasicBlockStart(const MachineBasicBlock *MBB) const;
-
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0);
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 68e70aae6a..a694033fa1 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -61,6 +61,35 @@ static gcp_map_type &getGCMap(void *&P) {
}
+/// getGVAlignmentLog2 - Return the alignment to use for the specified global
+/// value in log2 form. This rounds up to the preferred alignment if possible
+/// and legal.
+static unsigned getGVAlignmentLog2(const GlobalValue *GV, const TargetData &TD,
+ unsigned InBits = 0) {
+ unsigned NumBits = 0;
+ if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
+ NumBits = TD.getPreferredAlignmentLog(GVar);
+
+ // If InBits is specified, round it to it.
+ if (InBits > NumBits)
+ NumBits = InBits;
+
+ // If the GV has a specified alignment, take it into account.
+ if (GV->getAlignment() == 0)
+ return NumBits;
+
+ unsigned GVAlign = Log2_32(GV->getAlignment());
+
+ // If the GVAlign is larger than NumBits, or if we are required to obey
+ // NumBits because the GV has an assigned section, obey it.
+ if (GVAlign > NumBits || GV->hasSection())
+ NumBits = GVAlign;
+ return NumBits;
+}
+
+
+
+
AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
: MachineFunctionPass(&ID),
TM(tm), MAI(tm.getMCAsmInfo()),
@@ -227,16 +256,12 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
const TargetData *TD = TM.getTargetData();
- unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType());
+ uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
// If the alignment is specified, we *must* obey it. Overaligning a global
// with a specified alignment is a prompt way to break globals emitted to
// sections and expected to be contiguous (e.g. ObjC metadata).
- unsigned AlignLog;
- if (unsigned GVAlign = GV->getAlignment())
- AlignLog = Log2_32(GVAlign);
- else
- AlignLog = TD->getPreferredAlignmentLog(GV);
+ unsigned AlignLog = getGVAlignmentLog2(GV, *TD);
// Handle common and BSS local symbols (.lcomm).
if (GVKind.isCommon() || GVKind.isBSSLocal()) {
@@ -1010,7 +1035,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
unsigned Align = Log2_32(TD->getPointerPrefAlignment());
if (GV->getName() == "llvm.global_ctors") {
OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection());
- EmitAlignment(Align, 0);
+ EmitAlignment(Align);
EmitXXStructorList(GV->getInitializer());
if (TM.getRelocationModel() == Reloc::Static &&
@@ -1024,7 +1049,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
if (GV->getName() == "llvm.global_dtors") {
OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection());
- EmitAlignment(Align, 0);
+ EmitAlignment(Align);
EmitXXStructorList(GV->getInitializer());
if (TM.getRelocationModel() == Reloc::Static &&
@@ -1153,20 +1178,13 @@ void AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
// EmitAlignment - Emit an alignment directive to the specified power of
// two boundary. For example, if you pass in 3 here, you will get an 8
// byte alignment. If a global value is specified, and if that global has
-// an explicit alignment requested, it will unconditionally override the
-// alignment request. However, if ForcedAlignBits is specified, this value
-// has final say: the ultimate alignment will be the max of ForcedAlignBits
-// and the alignment computed with NumBits and the global.
-//
-// The algorithm is:
-// Align = NumBits;
-// if (GV && GV->hasalignment) Align = GV->getAlignment();
+// an explicit alignment requested, it will override the alignment request
+// if required for correctness.
//
void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
- if (GV && GV->getAlignment())
- NumBits = Log2_32(GV->getAlignment());
+ if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits);
- if (NumBits == 0) return; // No need to emit alignment.
+ if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment.
if (getCurrentSection()->getKind().isText())
OutStreamer.EmitCodeAlignment(1 << NumBits);
diff --git a/test/CodeGen/X86/alignment.ll b/test/CodeGen/X86/alignment.ll
index 06a4f3f8e8..9678e6df74 100644
--- a/test/CodeGen/X86/alignment.ll
+++ b/test/CodeGen/X86/alignment.ll
@@ -6,7 +6,7 @@
; CHECK: .bss
; CHECK: .globl GlobalA
-; CHECK: .align 8
+; CHECK: .align 16
; CHECK: GlobalA:
; CHECK: .zero 384
@@ -15,4 +15,29 @@
; PR6921
@GlobalB = common global { [384 x i8] } zeroinitializer, align 8
-; CHECK: .comm GlobalB,384,8 \ No newline at end of file
+; CHECK: .comm GlobalB,384,16
+
+
+@GlobalC = common global { [384 x i8] } zeroinitializer, align 2
+
+; CHECK: .comm GlobalC,384,16
+
+
+
+; This cannot get rounded up to the preferred alignment (16) if they have an
+; explicit alignment specified *and* a section specified.
+@GlobalAS = global { [384 x i8] } zeroinitializer, align 8, section "foo"
+
+; CHECK: .globl GlobalAS
+; CHECK: .align 8
+; CHECK: GlobalAS:
+; CHECK: .zero 384
+
+; Common variables should not get rounded up to the preferred alignment (16) if
+; they have an explicit alignment specified and a section specified.
+; PR6921
+@GlobalBS = common global { [384 x i8] } zeroinitializer, align 8, section "foo"
+; CHECK: .comm GlobalBS,384,8
+
+@GlobalCS = common global { [384 x i8] } zeroinitializer, align 2, section "foo"
+; CHECK: .comm GlobalCS,384,2 \ No newline at end of file
diff --git a/test/CodeGen/X86/unaligned-load.ll b/test/CodeGen/X86/unaligned-load.ll
index b26097f31b..a99af0605b 100644
--- a/test/CodeGen/X86/unaligned-load.ll
+++ b/test/CodeGen/X86/unaligned-load.ll
@@ -29,8 +29,8 @@ return:
declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
; CORE2: .section
-; CORE2: .align 3
+; CORE2: .align 4
; CORE2-NEXT: _.str1:
; CORE2-NEXT: .asciz "DHRYSTONE PROGRAM, SOME STRING"
-; CORE2: .align 3
+; CORE2: .align 4
; CORE2-NEXT: _.str3:
diff --git a/test/FrontendC/cstring-align.c b/test/FrontendC/cstring-align.c
index 715d0f3126..b9ec281f56 100644
--- a/test/FrontendC/cstring-align.c
+++ b/test/FrontendC/cstring-align.c
@@ -1,6 +1,5 @@
// RUN: %llvmgcc %s -c -Os -m32 -emit-llvm -o - | llc -march=x86 -mtriple=i386-apple-darwin10 | FileCheck %s -check-prefix=DARWIN32
// RUN: %llvmgcc %s -c -Os -m64 -emit-llvm -o - | llc -march=x86-64 -mtriple=x86_64-apple-darwin10 | FileCheck %s -check-prefix=DARWIN64
-// XFAIL: *
// XTARGET: darwin
extern void func(const char *, const char *);
@@ -9,10 +8,10 @@ void long_function_name() {
func("%s: the function name", __func__);
}
-// DARWIN64: .align 3
+// DARWIN64: .align 4
// DARWIN64: ___func__.
// DARWIN64: .asciz "long_function_name"
-// DARWIN32: .align 2
+// DARWIN32: .align 4
// DARWIN32: ___func__.
// DARWIN32: .asciz "long_function_name"