diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2995,17 +2995,42 @@ } } +static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP); + static void emitGlobalConstantVector(const DataLayout &DL, 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); + Type *ElementType = CV->getType()->getElementType(); + uint64_t ElementSizeInBits = DL.getTypeSizeInBits(ElementType); + uint64_t ElementAllocSizeInBits = DL.getTypeAllocSizeInBits(ElementType); + uint64_t EmittedSize; + if (ElementSizeInBits != ElementAllocSizeInBits) { + // If the allocation size of an element is different from the size in bits, + // printing each element separately will insert incorrect padding. + // + // The general algorithm here is complicated; instead of writing it out + // here, just use the existing code in ConstantFolding. + Type *IntT = + IntegerType::get(CV->getContext(), DL.getTypeSizeInBits(CV->getType())); + ConstantInt *CI = dyn_cast_or_null(ConstantFoldConstant( + ConstantExpr::getBitCast(const_cast(CV), IntT), DL)); + if (!CI) { + report_fatal_error( + "Cannot lower vector global with unusual element type"); + } + emitGlobalAliasInline(AP, 0, AliasList); + emitGlobalConstantLargeInt(CI, AP); + EmittedSize = DL.getTypeStoreSize(CV->getType()); + } else { + 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); + } + EmittedSize = + DL.getTypeAllocSize(ElementType) * CV->getType()->getNumElements(); } unsigned Size = DL.getTypeAllocSize(CV->getType()); - unsigned EmittedSize = DL.getTypeAllocSize(CV->getType()->getElementType()) * - CV->getType()->getNumElements(); if (unsigned Padding = Size - EmittedSize) AP.OutStreamer->emitZeros(Padding); } diff --git a/llvm/test/CodeGen/AArch64/vector-global-i1.ll b/llvm/test/CodeGen/AArch64/vector-global-i1.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/vector-global-i1.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple aarch64 | FileCheck %s + +; CHECK: a: +; CHECK-NEXT: .zero 1 +@a = internal constant <4 x i1> +; CHECK: b: +; CHECK-NEXT: .byte 5 +@b = internal constant <4 x i1> +; CHECK: c: +; CHECK-NEXT: .hword 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .zero 1 +@c = internal constant <24 x i1> +