[llvm] d2a35e4 - [AIX] Handling the label alignment of a global
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 3 20:18:28 PDT 2022
Author: esmeyi
Date: 2022-07-03T23:16:16-04:00
New Revision: d2a35e4d39fec0c328f9bb05ad3ea7134751a64e
URL: https://github.com/llvm/llvm-project/commit/d2a35e4d39fec0c328f9bb05ad3ea7134751a64e
DIFF: https://github.com/llvm/llvm-project/commit/d2a35e4d39fec0c328f9bb05ad3ea7134751a64e.diff
LOG: [AIX] Handling the label alignment of a global
variable with its multiple aliases.
This patch handles the case where a variable has
multiple aliases.
AIX's assembly directive .set is not usable for the
aliasing purpose, and using different labels allows
AIX to emulate symbol aliases. If a value is emitted
between any two labels, meaning they are not aligned,
XCOFF will automatically calculate the offset for them.
This patch implements:
1) Emits the label of the alias just before emitting
the value of the sub-element that the alias referred to.
2) A set of aliases that refers to the same offset
should be aligned.
3) We didn't emit aliasing labels for common and
zero-initialized local symbols in
PPCAIXAsmPrinter::emitGlobalVariableHelper, but
emitted linkage for them in
AsmPrinter::emitGlobalAlias, which caused a FAILURE.
This patch fixes the bug by blocking emitting linkage
for the alias without a label.
Reviewed By: shchenz
Differential Revision: https://reviews.llvm.org/D124654
Added:
llvm/test/CodeGen/PowerPC/aix-alias-alignment-2.ll
llvm/test/CodeGen/PowerPC/aix-alias-alignment.ll
Modified:
llvm/include/llvm/CodeGen/AsmPrinter.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/test/CodeGen/PowerPC/aix-alias.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index fb4627c029b04..5e900e9162d8e 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -41,6 +41,7 @@ class DIEAbbrev;
class DwarfDebug;
class GCMetadataPrinter;
class GCStrategy;
+class GlobalAlias;
class GlobalObject;
class GlobalValue;
class GlobalVariable;
@@ -474,7 +475,11 @@ class AsmPrinter : public MachineFunctionPass {
virtual const MCExpr *lowerConstant(const Constant *CV);
/// Print a general LLVM constant to the .s file.
- void emitGlobalConstant(const DataLayout &DL, const Constant *CV);
+ /// On AIX, when an alias refers to a sub-element of a global variable, the
+ /// label of that alias needs to be emitted before the corresponding element.
+ using AliasMapTy = DenseMap<uint64_t, SmallVector<const GlobalAlias *, 1>>;
+ void emitGlobalConstant(const DataLayout &DL, const Constant *CV,
+ AliasMapTy *AliasList = nullptr);
/// Unnamed constant global variables solely contaning a pointer to
/// another globals variable act like a global variable "proxy", or GOT
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 4a31bf85446be..86293c7a4bf37 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1816,6 +1816,11 @@ void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) {
if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
assert(MAI->hasVisibilityOnlyWithLinkage() &&
"Visibility should be handled with emitLinkage() on AIX.");
+
+ // Linkage for alias of global variable has been emitted.
+ if (isa<GlobalVariable>(GA.getAliaseeObject()))
+ return;
+
emitLinkage(&GA, Name);
// If it's a function, also emit linkage for aliases of function entry
// point.
@@ -2860,7 +2865,8 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *C,
AsmPrinter &AP,
const Constant *BaseCV = nullptr,
- uint64_t Offset = 0);
+ uint64_t Offset = 0,
+ AsmPrinter::AliasMapTy *AliasList = nullptr);
static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP);
static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP);
@@ -2914,9 +2920,21 @@ static int isRepeatedByteSequence(const Value *V, const DataLayout &DL) {
return -1;
}
-static void emitGlobalConstantDataSequential(const DataLayout &DL,
- const ConstantDataSequential *CDS,
- AsmPrinter &AP) {
+static void emitGlobalAliasInline(AsmPrinter &AP, uint64_t Offset,
+ AsmPrinter::AliasMapTy *AliasList) {
+ if (AliasList) {
+ auto AliasIt = AliasList->find(Offset);
+ if (AliasIt != AliasList->end()) {
+ for (const GlobalAlias *GA : AliasIt->second)
+ AP.OutStreamer->emitLabel(AP.getSymbol(GA));
+ AliasList->erase(Offset);
+ }
+ }
+}
+
+static void emitGlobalConstantDataSequential(
+ const DataLayout &DL, const ConstantDataSequential *CDS, AsmPrinter &AP,
+ AsmPrinter::AliasMapTy *AliasList) {
// See if we can aggregate this into a .fill, if so, emit it as such.
int Value = isRepeatedByteSequence(CDS, DL);
if (Value != -1) {
@@ -2933,17 +2951,20 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL,
// Otherwise, emit the values in successive locations.
unsigned ElementByteSize = CDS->getElementByteSize();
if (isa<IntegerType>(CDS->getElementType())) {
- for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
+ for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
+ emitGlobalAliasInline(AP, ElementByteSize * I, AliasList);
if (AP.isVerbose())
AP.OutStreamer->getCommentOS()
- << format("0x%" PRIx64 "\n", CDS->getElementAsInteger(i));
- AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(i),
+ << format("0x%" PRIx64 "\n", CDS->getElementAsInteger(I));
+ AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(I),
ElementByteSize);
}
} else {
Type *ET = CDS->getElementType();
- for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I)
+ for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
+ emitGlobalAliasInline(AP, ElementByteSize * I, AliasList);
emitGlobalConstantFP(CDS->getElementAsAPFloat(I), ET, AP);
+ }
}
unsigned Size = DL.getTypeAllocSize(CDS->getType());
@@ -2956,7 +2977,8 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL,
static void emitGlobalConstantArray(const DataLayout &DL,
const ConstantArray *CA, AsmPrinter &AP,
- const Constant *BaseCV, uint64_t Offset) {
+ const Constant *BaseCV, uint64_t Offset,
+ AsmPrinter::AliasMapTy *AliasList) {
// See if we can aggregate some values. Make sure it can be
// represented as a series of bytes of the constant value.
int Value = isRepeatedByteSequence(CA, DL);
@@ -2964,19 +2986,22 @@ static void emitGlobalConstantArray(const DataLayout &DL,
if (Value != -1) {
uint64_t Bytes = DL.getTypeAllocSize(CA->getType());
AP.OutStreamer->emitFill(Bytes, Value);
- }
- else {
- for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
- emitGlobalConstantImpl(DL, CA->getOperand(i), AP, BaseCV, Offset);
- Offset += DL.getTypeAllocSize(CA->getOperand(i)->getType());
+ } else {
+ for (unsigned I = 0, E = CA->getNumOperands(); I != E; ++I) {
+ emitGlobalConstantImpl(DL, CA->getOperand(I), AP, BaseCV, Offset,
+ AliasList);
+ Offset += DL.getTypeAllocSize(CA->getOperand(I)->getType());
}
}
}
static void emitGlobalConstantVector(const DataLayout &DL,
- const ConstantVector *CV, AsmPrinter &AP) {
- for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
- emitGlobalConstantImpl(DL, CV->getOperand(i), AP);
+ const ConstantVector *CV, AsmPrinter &AP,
+ AsmPrinter::AliasMapTy *AliasList) {
+ for (unsigned I = 0, E = CV->getType()->getNumElements(); I != E; ++I) {
+ emitGlobalAliasInline(AP, DL.getTypeAllocSize(CV->getType()) * I, AliasList);
+ emitGlobalConstantImpl(DL, CV->getOperand(I), AP);
+ }
unsigned Size = DL.getTypeAllocSize(CV->getType());
unsigned EmittedSize = DL.getTypeAllocSize(CV->getType()->getElementType()) *
@@ -2987,21 +3012,24 @@ static void emitGlobalConstantVector(const DataLayout &DL,
static void emitGlobalConstantStruct(const DataLayout &DL,
const ConstantStruct *CS, AsmPrinter &AP,
- const Constant *BaseCV, uint64_t Offset) {
+ const Constant *BaseCV, uint64_t Offset,
+ AsmPrinter::AliasMapTy *AliasList) {
// Print the fields in successive locations. Pad to align if needed!
unsigned Size = DL.getTypeAllocSize(CS->getType());
const StructLayout *Layout = DL.getStructLayout(CS->getType());
uint64_t SizeSoFar = 0;
- for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
- const Constant *Field = CS->getOperand(i);
+ for (unsigned I = 0, E = CS->getNumOperands(); I != E; ++I) {
+ const Constant *Field = CS->getOperand(I);
// Print the actual field value.
- emitGlobalConstantImpl(DL, Field, AP, BaseCV, Offset + SizeSoFar);
+ emitGlobalConstantImpl(DL, Field, AP, BaseCV, Offset + SizeSoFar,
+ AliasList);
// Check if padding is needed and insert one or more 0s.
uint64_t FieldSize = DL.getTypeAllocSize(Field->getType());
- uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1))
- - Layout->getElementOffset(i)) - FieldSize;
+ uint64_t PadSize = ((I == E - 1 ? Size : Layout->getElementOffset(I + 1)) -
+ Layout->getElementOffset(I)) -
+ FieldSize;
SizeSoFar += FieldSize + PadSize;
// Insert padding - this may include padding to increase the size of the
@@ -3211,7 +3239,9 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,
static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
AsmPrinter &AP, const Constant *BaseCV,
- uint64_t Offset) {
+ uint64_t Offset,
+ AsmPrinter::AliasMapTy *AliasList) {
+ emitGlobalAliasInline(AP, Offset, AliasList);
uint64_t Size = DL.getTypeAllocSize(CV->getType());
// Globals with sub-elements such as combinations of arrays and structs
@@ -3251,13 +3281,13 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
}
if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV))
- return emitGlobalConstantDataSequential(DL, CDS, AP);
+ return emitGlobalConstantDataSequential(DL, CDS, AP, AliasList);
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
- return emitGlobalConstantArray(DL, CVA, AP, BaseCV, Offset);
+ return emitGlobalConstantArray(DL, CVA, AP, BaseCV, Offset, AliasList);
if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
- return emitGlobalConstantStruct(DL, CVS, AP, BaseCV, Offset);
+ return emitGlobalConstantStruct(DL, CVS, AP, BaseCV, Offset, AliasList);
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
// Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of
@@ -3276,7 +3306,7 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
}
if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
- return emitGlobalConstantVector(DL, V, AP);
+ return emitGlobalConstantVector(DL, V, AP, AliasList);
// Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it
// thread the streamer with EmitValue.
@@ -3292,10 +3322,11 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
}
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
-void AsmPrinter::emitGlobalConstant(const DataLayout &DL, const Constant *CV) {
+void AsmPrinter::emitGlobalConstant(const DataLayout &DL, const Constant *CV,
+ AliasMapTy *AliasList) {
uint64_t Size = DL.getTypeAllocSize(CV->getType());
if (Size)
- emitGlobalConstantImpl(DL, CV, *this);
+ emitGlobalConstantImpl(DL, CV, *this, nullptr, 0, AliasList);
else if (MAI->hasSubsectionsViaSymbols()) {
// If the global has zero size, emit a single byte so that two labels don't
// look like they are at the same location.
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 22f35c8fa8d3b..b692e6bafea34 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -230,6 +230,9 @@ class PPCAIXAsmPrinter : public PPCAsmPrinter {
void emitGlobalVariableHelper(const GlobalVariable *);
+ // Get the offset of an alias based on its AliaseeObject.
+ uint64_t getAliasOffset(const Constant *C);
+
public:
PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
: PPCAsmPrinter(TM, std::move(Streamer)) {
@@ -2352,6 +2355,24 @@ static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) {
.Default(false);
}
+uint64_t PPCAIXAsmPrinter::getAliasOffset(const Constant *C) {
+ if (auto *GA = dyn_cast<GlobalAlias>(C))
+ return getAliasOffset(GA->getAliasee());
+ if (auto *CE = dyn_cast<ConstantExpr>(C)) {
+ const MCExpr *LowC = lowerConstant(CE);
+ const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
+ if (!CBE)
+ return 0;
+ if (CBE->getOpcode() != MCBinaryExpr::Add)
+ report_fatal_error("Only adding an offset is supported now.");
+ auto *RHS = dyn_cast<MCConstantExpr>(CBE->getRHS());
+ if (!RHS)
+ report_fatal_error("Unable to get the offset of alias.");
+ return RHS->getValue();
+ }
+ return 0;
+}
+
void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
// Special LLVM global arrays have been handled at the initialization.
if (isSpecialLLVMGlobalArrayToSkip(GV) || isSpecialLLVMGlobalArrayForStaticInit(GV))
@@ -2422,20 +2443,34 @@ void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
}
MCSymbol *EmittedInitSym = GVSym;
+
+ // Emit linkage for the global variable and its aliases.
emitLinkage(GV, EmittedInitSym);
+ for (const GlobalAlias *GA : GOAliasMap[GV])
+ emitLinkage(GA, getSymbol(GA));
+
emitAlignment(getGVAlignment(GV, DL), GV);
// When -fdata-sections is enabled, every GlobalVariable will
// be put into its own csect; therefore, label is not necessary here.
- if (!TM.getDataSections() || GV->hasSection()) {
+ if (!TM.getDataSections() || GV->hasSection())
OutStreamer->emitLabel(EmittedInitSym);
+
+ // No alias to emit.
+ if (!GOAliasMap[GV].size()) {
+ emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
+ return;
}
- // Emit aliasing label for global variable.
- for (const GlobalAlias *Alias : GOAliasMap[GV])
- OutStreamer->emitLabel(getSymbol(Alias));
+ // Aliases with the same offset should be aligned. Record the list of aliases
+ // associated with the offset.
+ AliasMapTy AliasList;
+ for (const GlobalAlias *GA : GOAliasMap[GV])
+ AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
- emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
+ // Emit alias label and element value for global variable.
+ emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer(),
+ &AliasList);
}
void PPCAIXAsmPrinter::emitFunctionDescriptor() {
diff --git a/llvm/test/CodeGen/PowerPC/aix-alias-alignment-2.ll b/llvm/test/CodeGen/PowerPC/aix-alias-alignment-2.ll
new file mode 100644
index 0000000000000..18061d61a0ada
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-alias-alignment-2.ll
@@ -0,0 +1,79 @@
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
+; RUN: -data-sections=false < %s | FileCheck --check-prefix=ASM %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
+; RUN: -data-sections=false -filetype=obj -o %t.o < %s
+; RUN: llvm-objdump --syms %t.o | FileCheck --check-prefix=SYM %s
+
+ at ConstVector = global <2 x i64> <i64 12, i64 34>, align 4
+ at var1 = alias i64, getelementptr inbounds (<2 x i64>, <2 x i64>* @ConstVector, i32 0, i32 1)
+define void @foo1(i64 %a1) {
+ store i64 %a1, i64* getelementptr inbounds (<2 x i64>, <2 x i64>* @ConstVector, i32 0, i32 1), align 4
+ ret void
+}
+
+; ASM: .globl ConstVector # @ConstVector
+; ASM-NEXT: .globl var1
+; ASM-NEXT: .align 4
+; ASM-NEXT: ConstVector:
+; ASM-NEXT: .vbyte 4, 0 # 0xc
+; ASM-NEXT: .vbyte 4, 12
+; ASM-NEXT: var1:
+; ASM-NEXT: .vbyte 4, 0 # 0x22
+; ASM-NEXT: .vbyte 4, 34
+
+ at ConstDataSeq = global [2 x i64] [i64 12, i64 34], align 4
+ at var2 = alias i64, getelementptr inbounds ([2 x i64], [2 x i64]* @ConstDataSeq, i32 0, i32 1)
+define void @foo2(i64 %a1) {
+ store i64 %a1, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @ConstDataSeq, i32 0, i32 1), align 4
+ ret void
+}
+
+; ASM: .globl ConstDataSeq # @ConstDataSeq
+; ASM-NEXT: .globl var2
+; ASM-NEXT: .align 3
+; ASM-NEXT: ConstDataSeq:
+; ASM-NEXT: .vbyte 4, 0 # 0xc
+; ASM-NEXT: .vbyte 4, 12
+; ASM-NEXT: var2:
+; ASM-NEXT: .vbyte 4, 0 # 0x22
+; ASM-NEXT: .vbyte 4, 34
+
+%struct.B = type { i64 }
+ at ConstArray = global [2 x %struct.B] [%struct.B {i64 12}, %struct.B {i64 34}], align 4
+ at var3 = alias %struct.B, getelementptr inbounds ([2 x %struct.B], [2 x %struct.B]* @ConstArray, i32 0, i32 0)
+define void @foo3(%struct.B %a1) {
+ store %struct.B %a1, %struct.B* getelementptr inbounds ([2 x %struct.B], [2 x %struct.B]* @ConstArray, i32 0, i32 1), align 4
+ ret void
+}
+
+; ASM: .globl ConstArray # @ConstArray
+; ASM-NEXT: .globl var3
+; ASM-NEXT: .align 3
+; ASM-NEXT: ConstArray:
+; ASM-NEXT: var3:
+; ASM-NEXT: .vbyte 4, 0 # 0xc
+; ASM-NEXT: .vbyte 4, 12
+; ASM-NEXT: .vbyte 4, 0 # 0x22
+; ASM-NEXT: .vbyte 4, 34
+
+; SYM: SYMBOL TABLE:
+; SYM-NEXT: 00000000 df *DEBUG* 00000000 <stdin>
+; SYM-NEXT: 00000000 l .text 0000008a .text
+; SYM-NEXT: 00000000 g F .text (csect: .text) 00000000 .foo1
+; SYM-NEXT: 00000030 g F .text (csect: .text) 00000000 .foo2
+; SYM-NEXT: 00000060 g F .text (csect: .text) 00000000 .foo3
+; SYM-NEXT: 00000090 l .data 00000030 .data
+; SYM-NEXT: 00000090 g O .data (csect: .data) 00000000 ConstVector
+; SYM-NEXT: 00000098 g O .data (csect: .data) 00000000 var1
+; SYM-NEXT: 000000a0 g O .data (csect: .data) 00000000 ConstDataSeq
+; SYM-NEXT: 000000a8 g O .data (csect: .data) 00000000 var2
+; SYM-NEXT: 000000b0 g O .data (csect: .data) 00000000 ConstArray
+; SYM-NEXT: 000000b0 g O .data (csect: .data) 00000000 var3
+; SYM-NEXT: 000000c0 g O .data 0000000c foo1
+; SYM-NEXT: 000000cc g O .data 0000000c foo2
+; SYM-NEXT: 000000d8 g O .data 0000000c foo3
+; SYM-NEXT: 000000e4 l .data 00000000 TOC
+; SYM-NEXT: 000000e4 l O .data 00000004 ConstVector
+; SYM-NEXT: 000000e8 l O .data 00000004 ConstDataSeq
+; SYM-NEXT: 000000ec l O .data 00000004 ConstArray
diff --git a/llvm/test/CodeGen/PowerPC/aix-alias-alignment.ll b/llvm/test/CodeGen/PowerPC/aix-alias-alignment.ll
new file mode 100644
index 0000000000000..aa2db9dc7961b
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-alias-alignment.ll
@@ -0,0 +1,74 @@
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
+; RUN: -data-sections=false < %s | FileCheck --check-prefix=ASM %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
+; RUN: -data-sections=true < %s | FileCheck --check-prefix=ASM-DATASECT %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
+; RUN: -data-sections=false -filetype=obj -o %t.o < %s
+; RUN: llvm-objdump -dr %t.o | FileCheck --check-prefix=OBJ %s
+; RUN: llvm-objdump --syms %t.o | FileCheck --check-prefix=SYM %s
+
+ at _MergedGlobals = global <{ i32, i32 }> <{ i32 1, i32 2 }>, align 4
+ at var1 = alias i32, getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @_MergedGlobals, i32 0, i32 0)
+ at var2 = alias i32, getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @_MergedGlobals, i32 0, i32 1)
+ at var3 = alias i32, i32* @var2
+
+define void @foo(i32 %a1, i32 %a2, i32 %a3) {
+ store i32 %a1, i32* getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @_MergedGlobals, i32 0, i32 0), align 4
+ store i32 %a2, i32* getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @_MergedGlobals, i32 0, i32 1), align 4
+ ret void
+}
+
+; ASM: # -- End function
+; ASM-NEXT: .csect .data[RW],2
+; ASM-NEXT: .globl _MergedGlobals # @_MergedGlobals
+; ASM-NEXT: .globl var1
+; ASM-NEXT: .globl var2
+; ASM-NEXT: .globl var3
+; ASM-NEXT: .align 2
+; ASM-NEXT: _MergedGlobals:
+; ASM-NEXT: var1:
+; ASM-NEXT: .vbyte 4, 1 # 0x1
+; ASM-NEXT: var2:
+; ASM-NEXT: var3:
+; ASM-NEXT: .vbyte 4, 2 # 0x2
+; ASM-NEXT: .toc
+; ASM-NEXT: L..C0:
+; ASM-NEXT: .tc _MergedGlobals[TC],_MergedGlobals
+
+; ASM-DATASECT: # -- End function
+; ASM-DATASECT-NEXT: .csect _MergedGlobals[RW],2
+; ASM-DATASECT-NEXT: .globl _MergedGlobals[RW] # @_MergedGlobals
+; ASM-DATASECT-NEXT: .globl var1
+; ASM-DATASECT-NEXT: .globl var2
+; ASM-DATASECT-NEXT: .globl var3
+; ASM-DATASECT-NEXT: .align 2
+; ASM-DATASECT-NEXT: var1:
+; ASM-DATASECT-NEXT: .vbyte 4, 1 # 0x1
+; ASM-DATASECT-NEXT: var2:
+; ASM-DATASECT-NEXT: var3:
+; ASM-DATASECT-NEXT: .vbyte 4, 2 # 0x2
+; ASM-DATASECT-NEXT: .toc
+; ASM-DATASECT-NEXT: L..C0:
+; ASM-DATASECT-NEXT: .tc _MergedGlobals[TC],_MergedGlobals[RW]
+
+; OBJ: 00000000 <.foo>:
+; OBJ-NEXT: 0: 80 a2 00 00 lwz 5, 0(2)
+; OBJ-NEXT: 00000002: R_TOC _MergedGlobals
+; OBJ-NEXT: 4: 90 65 00 00 stw 3, 0(5)
+; OBJ-NEXT: 8: 90 85 00 04 stw 4, 4(5)
+; OBJ-NEXT: c: 4e 80 00 20 blr
+
+; SYM: SYMBOL TABLE:
+; SYM-NEXT: 00000000 df *DEBUG* 00000000 <stdin>
+; SYM-NEXT: 00000000 l .text 00000029 .text
+; SYM-NEXT: 00000000 g F .text (csect: .text) 00000000 .foo
+; SYM-NEXT: 0000002c l .data 00000008 .data
+; SYM-NEXT: 0000002c g O .data (csect: .data) 00000000 _MergedGlobals
+; SYM-NEXT: 0000002c g O .data (csect: .data) 00000000 var1
+; SYM-NEXT: 00000030 g O .data (csect: .data) 00000000 var2
+; SYM-NEXT: 00000030 g O .data (csect: .data) 00000000 var3
+; SYM-NEXT: 00000034 g O .data 0000000c foo
+; SYM-NEXT: 00000040 l .data 00000000 TOC
+; SYM-NEXT: 00000040 l O .data 00000004 _MergedGlobals
diff --git a/llvm/test/CodeGen/PowerPC/aix-alias.ll b/llvm/test/CodeGen/PowerPC/aix-alias.ll
index be35fd526a498..837e84a52fbe1 100644
--- a/llvm/test/CodeGen/PowerPC/aix-alias.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-alias.ll
@@ -75,6 +75,12 @@ entry:
; ASM: # -- End function
; ASM-NEXT: .csect .data[RW]
; ASM-NEXT: .globl var
+; ASM-NEXT: .globl var1
+; ASM-NEXT: .globl var2
+; ASM-NEXT: .weak var_l
+; ASM-NEXT: .lglobl var_i
+; ASM-NEXT: .globl var_h,hidden
+; ASM-NEXT: .globl var_p,protected
; ASM: var:
; ASM-NEXT: var1:
; ASM-NEXT: var2:
@@ -83,24 +89,18 @@ entry:
; ASM-NEXT: var_h:
; ASM-NEXT: var_p:
; ASM-NEXT: .vbyte 4, 42
-; ASM-NEXT: .globl array
+; ASM-NEXT: .globl array
; ASM: array:
; ASM-NEXT: .vbyte 4, 1 # 0x1
; ASM-NEXT: .vbyte 4, 2 # 0x2
; ASM-NEXT: .globl x
+; ASM-NEXT: .globl bitcast_alias
; ASM: x:
; ASM-NEXT: bitcast_alias:
; ASM-NEXT: .vbyte {{[0-9]+}}, array+4
; ASM-NEXT: .globl fun_ptr
; ASM: fun_ptr:
; ASM-NEXT: .vbyte {{[0-9]+}}, fun_weak
-; ASM-NEXT: .globl var1
-; ASM-NEXT: .globl var2
-; ASM-NEXT: .weak var_l
-; ASM-NEXT: .lglobl var_i
-; ASM-NEXT: .globl var_h,hidden
-; ASM-NEXT: .globl var_p,protected
-; ASM-NEXT: .globl bitcast_alias
; ASM-NEXT: .weak fun_weak
; ASM-NEXT: .weak .fun_weak
; ASM-NEXT: .globl fun_hidden,hidden
More information about the llvm-commits
mailing list