[AsmPrinter] Fix handling in emitGlobalConstantImpl for AIX (#116255)

When GlobalMerge creates a MergedGlobal of statics all initialized to
zero, emitGlobalConstantImpl sees a ConstantAggregateZero. This results
in just emitting zeros followed by labels for the aliases. We need to
handle it more like how emitGlobalConstantStruct does by emitting each
global inside the aggregate.

---------

Co-authored-by: Hubert Tong <hubert.reinterpretcast@gmail.com>
This commit is contained in:
Zaara Syeda
2024-11-19 09:58:25 -05:00
committed by GitHub
parent aff98e4be0
commit 8e4423eb08
2 changed files with 75 additions and 1 deletions

View File

@@ -3849,6 +3849,8 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
AsmPrinter &AP, const Constant *BaseCV,
uint64_t Offset,
AsmPrinter::AliasMapTy *AliasList) {
assert(!AliasList || AP.TM.getTargetTriple().isOSBinFormatXCOFF() &&
"AliasList only expected for XCOFF");
emitGlobalAliasInline(AP, Offset, AliasList);
uint64_t Size = DL.getTypeAllocSize(CV->getType());
@@ -3858,7 +3860,27 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
if (!BaseCV && CV->hasOneUse())
BaseCV = dyn_cast<Constant>(CV->user_back());
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
if (isa<ConstantAggregateZero>(CV)) {
StructType *structType;
if (AliasList && (structType = llvm::dyn_cast<StructType>(CV->getType()))) {
// Handle cases of aliases to direct struct elements
const StructLayout *Layout = DL.getStructLayout(structType);
uint64_t SizeSoFar = 0;
for (unsigned int i = 0, n = structType->getNumElements(); i < n - 1;
++i) {
uint64_t GapToNext = Layout->getElementOffset(i + 1) - SizeSoFar;
AP.OutStreamer->emitZeros(GapToNext);
SizeSoFar += GapToNext;
emitGlobalAliasInline(AP, Offset + SizeSoFar, AliasList);
}
AP.OutStreamer->emitZeros(Size - SizeSoFar);
return;
} else {
return AP.OutStreamer->emitZeros(Size);
}
}
if (isa<UndefValue>(CV))
return AP.OutStreamer->emitZeros(Size);
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {

View File

@@ -0,0 +1,52 @@
; RUN: rm -rf %t
; RUN: mkdir -p %t
; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr8 < %s | FileCheck %s
; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr8 --filetype=obj -o %t/global-merge-aix-sections.o < %s
; RUN; llvm-objdump --syms %t/global-merge-aix-sections.o | FileCheck %s --check-prefix=DATA
%struct.Example = type { i32, i8 }
@y = internal global i32 0, section "mycsect", align 4
@z = internal global i32 0, section "mycsect", align 4
@l = internal global i32 0, align 4
@u = internal global i16 0, section "mycsect", align 2
@myStruct1 = internal global %struct.Example zeroinitializer, section "mycsect", align 4
; Function Attrs: nounwind
define void @g() {
entry:
tail call void @f(ptr noundef nonnull @y, ptr noundef nonnull @z)
tail call void @f(ptr noundef nonnull @l, ptr noundef nonnull @z)
tail call void @h(ptr noundef nonnull @u)
tail call void @s(ptr noundef nonnull @myStruct1)
ret void
}
declare void @f(ptr noundef, ptr noundef)
declare void @h(ptr noundef)
declare void @s(ptr noundef)
; CHECK: .csect mycsect[RW],2
; CHECK-NEXT: .lglobl u # @_MergedGlobals
; CHECK-NEXT: .lglobl y
; CHECK-NEXT: .lglobl z
; CHECK-NEXT: .lglobl myStruct1
; CHECK-NEXT: .align 2
; CHECK-NEXT: L.._MergedGlobals:
; CHECK-NEXT: u:
; CHECK-NEXT: .space 2
; CHECK-NEXT: .space 2
; CHECK-NEXT: y:
; CHECK-NEXT: .space 4
; CHECK-NEXT: z:
; CHECK-NEXT: .space 4
; CHECK-NEXT: myStruct1:
; CHECK-NEXT: .space 8
; DATA: 00000078 l O .data 00000014 mycsect
; DATA-NEXT: 00000078 l O .data (csect: mycsect) 00000000 u
; DATA-NEXT: 0000007c l O .data (csect: mycsect) 00000000 y
; DATA-NEXT: 00000080 l O .data (csect: mycsect) 00000000 z
; DATA-NEXT: 00000084 l O .data (csect: mycsect) 00000000 myStruct1