summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-09-07 21:08:01 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-09-07 21:08:01 +0000
commit68b9f0583f6af28c4912367899e4156edee3c3d0 (patch)
treed21d85fdc8f62496a06b06fd2fb3c34f8e933bc3
parent2c39b77f894579c367e8b4dd640193a7d92aa876 (diff)
downloadbcm5719-llvm-68b9f0583f6af28c4912367899e4156edee3c3d0.tar.gz
bcm5719-llvm-68b9f0583f6af28c4912367899e4156edee3c3d0.zip
Fix alignment of .comm and .lcomm on mingw32.
For some reason .lcomm uses byte alignment and .comm log2 alignment so we can't use the same setting for both. Fix this by reintroducing the LCOMM enum. I verified this against mingw's gcc. llvm-svn: 163420
-rw-r--r--llvm/include/llvm/MC/MCAsmInfo.h14
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp3
-rw-r--r--llvm/lib/MC/MCAsmInfo.cpp2
-rw-r--r--llvm/lib/MC/MCAsmInfoCOFF.cpp6
-rw-r--r--llvm/lib/MC/MCAsmInfoDarwin.cpp2
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp11
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp6
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp2
-rw-r--r--llvm/test/MC/COFF/comm.ll13
9 files changed, 42 insertions, 17 deletions
diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h
index 73709364fef..97aad71fd95 100644
--- a/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/llvm/include/llvm/MC/MCAsmInfo.h
@@ -32,6 +32,10 @@ namespace llvm {
enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 };
}
+ namespace LCOMM {
+ enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
+ }
+
/// MCAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target.
class MCAsmInfo {
@@ -247,9 +251,9 @@ namespace llvm {
/// alignment is to be specified in bytes instead of log2(n).
bool COMMDirectiveAlignmentIsInBytes; // Defaults to true;
- /// LCOMMDirectiveSupportsAlignment - True if .lcomm supports an optional
- /// alignment argument on this target.
- bool LCOMMDirectiveSupportsAlignment; // Defaults to false.
+ /// LCOMMDirectiveAlignment - Describes if the .lcomm directive for the
+ /// target supports an alignment argument and how it is interpreted.
+ LCOMM::LCOMMType LCOMMDirectiveAlignmentType; // Defaults to NoAlignment.
/// HasDotTypeDotSizeDirective - True if the target has .type and .size
/// directives, this is true for most ELF targets.
@@ -495,8 +499,8 @@ namespace llvm {
bool getCOMMDirectiveAlignmentIsInBytes() const {
return COMMDirectiveAlignmentIsInBytes;
}
- bool getLCOMMDirectiveSupportsAlignment() const {
- return LCOMMDirectiveSupportsAlignment;
+ LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
+ return LCOMMDirectiveAlignmentType;
}
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 2aae37696ba..d6d45104098 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -312,7 +312,8 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return;
}
- if (Align == 1 || MAI->getLCOMMDirectiveSupportsAlignment()) {
+ if (Align == 1 ||
+ MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {
// .lcomm _foo, 42
OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align);
return;
diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp
index 11e368c81a3..7ea0f3b85a5 100644
--- a/llvm/lib/MC/MCAsmInfo.cpp
+++ b/llvm/lib/MC/MCAsmInfo.cpp
@@ -69,7 +69,7 @@ MCAsmInfo::MCAsmInfo() {
HasSetDirective = true;
HasAggressiveSymbolFolding = true;
COMMDirectiveAlignmentIsInBytes = true;
- LCOMMDirectiveSupportsAlignment = false;
+ LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
HasDotTypeDotSizeDirective = true;
HasSingleParameterDotFile = true;
HasNoDeadStrip = false;
diff --git a/llvm/lib/MC/MCAsmInfoCOFF.cpp b/llvm/lib/MC/MCAsmInfoCOFF.cpp
index 4b426f8a731..fd79193073d 100644
--- a/llvm/lib/MC/MCAsmInfoCOFF.cpp
+++ b/llvm/lib/MC/MCAsmInfoCOFF.cpp
@@ -19,8 +19,10 @@ void MCAsmInfoCOFF::anchor() { }
MCAsmInfoCOFF::MCAsmInfoCOFF() {
GlobalPrefix = "_";
- COMMDirectiveAlignmentIsInBytes = true;
- LCOMMDirectiveSupportsAlignment = true;
+ // MingW 4.5 and later support .comm with log2 alignment, but .lcomm uses byte
+ // alignment.
+ COMMDirectiveAlignmentIsInBytes = false;
+ LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
HasDotTypeDotSizeDirective = false;
HasSingleParameterDotFile = false;
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
diff --git a/llvm/lib/MC/MCAsmInfoDarwin.cpp b/llvm/lib/MC/MCAsmInfoDarwin.cpp
index 99520d4bf9a..a0e3ebad5e2 100644
--- a/llvm/lib/MC/MCAsmInfoDarwin.cpp
+++ b/llvm/lib/MC/MCAsmInfoDarwin.cpp
@@ -32,7 +32,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
AlignmentIsInBytes = false;
COMMDirectiveAlignmentIsInBytes = false;
- LCOMMDirectiveSupportsAlignment = true;
+ LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
InlineAsmStart = " InlineAsm Start";
InlineAsmEnd = " InlineAsm End";
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 804e38ead08..b0bc2900ecb 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -519,13 +519,16 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlign) {
OS << "\t.lcomm\t" << *Symbol << ',' << Size;
if (ByteAlign > 1) {
- assert(MAI.getLCOMMDirectiveSupportsAlignment() &&
- "alignment not supported on .lcomm!");
- if (MAI.getCOMMDirectiveAlignmentIsInBytes()) {
+ switch (MAI.getLCOMMDirectiveAlignmentType()) {
+ case LCOMM::NoAlignment:
+ llvm_unreachable("alignment not supported on .lcomm!");
+ case LCOMM::ByteAlignment:
OS << ',' << ByteAlign;
- } else {
+ break;
+ case LCOMM::Log2Alignment:
assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
OS << ',' << Log2_32(ByteAlign);
+ break;
}
}
EmitEOL();
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 271fee02ada..55ef01c7961 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -2280,11 +2280,13 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
if (ParseAbsoluteExpression(Pow2Alignment))
return true;
- if (IsLocal && !Lexer.getMAI().getLCOMMDirectiveSupportsAlignment())
+ LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
+ if (IsLocal && LCOMM == LCOMM::NoAlignment)
return Error(Pow2AlignmentLoc, "alignment not supported on this target");
// If this target takes alignments in bytes (not log) validate and convert.
- if (Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) {
+ if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
+ (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
if (!isPowerOf2_64(Pow2Alignment))
return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
Pow2Alignment = Log2_64(Pow2Alignment);
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
index ec6b721f127..86f75d1c2d7 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
@@ -24,7 +24,7 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) {
HasLEB128 = true;
PrivateGlobalPrefix = ".L";
- LCOMMDirectiveSupportsAlignment = true;
+ LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
InlineAsmStart = "# InlineAsm Start";
InlineAsmEnd = "# InlineAsm End";
ZeroDirective = "\t.space\t";
diff --git a/llvm/test/MC/COFF/comm.ll b/llvm/test/MC/COFF/comm.ll
new file mode 100644
index 00000000000..74da557fb5c
--- /dev/null
+++ b/llvm/test/MC/COFF/comm.ll
@@ -0,0 +1,13 @@
+; RUN: llc -mtriple i386-pc-mingw32 < %s | FileCheck %s
+
+@a = internal global i8 0, align 1
+@b = internal global double 0.000000e+00, align 8
+@c = common global i8 0, align 1
+@d = common global double 0.000000e+00, align 8
+
+; .lcomm uses byte alignment
+; CHECK: .lcomm _a,1
+; CHECK: .lcomm _b,8,8
+; .comm uses log2 alignment
+; CHECK: .comm _c,1,0
+; CHECK: .comm _d,8,3
OpenPOWER on IntegriCloud