From: David Majnemer Date: Tue, 15 Jul 2014 02:34:12 +0000 (+0000) Subject: CodeGen: Handle ConstantVector and undef in WinCOFF constant pools X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cdc1044944cded7cf9236c25e0f5bf36624061eb;p=oota-llvm.git CodeGen: Handle ConstantVector and undef in WinCOFF constant pools The constant pool entry code for WinCOFF assumed that vector constants would be formed using ConstantDataVector, it did not expect to see a ConstantVector. Furthermore, it did not expect undef as one of the elements of the vector. ConstantVectors should be handled like ConstantDataVectors, treat Undef as zero. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213038 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp index c7802320b06..21ee047594b 100644 --- a/lib/Target/X86/X86TargetObjectFile.cpp +++ b/lib/Target/X86/X86TargetObjectFile.cpp @@ -109,7 +109,8 @@ const MCExpr *X86WindowsTargetObjectFile::getExecutableRelativeSymbol( getContext()); } -static std::string APIntToHexString(const APInt &AI, unsigned Width) { +static std::string APIntToHexString(const APInt &AI) { + unsigned Width = (AI.getBitWidth() / 8) * 2; std::string HexString = utohexstr(AI.getLimitedValue(), /*LowerCase=*/true); unsigned Size = HexString.size(); assert(Width >= Size && "hex string is too large!"); @@ -121,17 +122,19 @@ static std::string APIntToHexString(const APInt &AI, unsigned Width) { static std::string scalarConstantToHexString(const Constant *C) { Type *Ty = C->getType(); - if (Ty->isFloatTy()) { + APInt AI; + if (isa(C)) { + AI = APInt(Ty->getPrimitiveSizeInBits(), /*val=*/0); + } else if (Ty->isFloatTy() || Ty->isDoubleTy()) { const auto *CFP = cast(C); - return APIntToHexString(CFP->getValueAPF().bitcastToAPInt(), /*Width=*/8); - } else if (Ty->isDoubleTy()) { - const auto *CFP = cast(C); - return APIntToHexString(CFP->getValueAPF().bitcastToAPInt(), /*Width=*/16); - } else if (const auto *ITy = dyn_cast(Ty)) { + AI = CFP->getValueAPF().bitcastToAPInt(); + } else if (Ty->isIntegerTy()) { const auto *CI = cast(C); - return APIntToHexString(CI->getValue(), (ITy->getBitWidth() / 8) * 2); + AI = CI->getValue(); + } else { + llvm_unreachable("unexpected constant pool element type!"); } - llvm_unreachable("unexpected constant pool element type!"); + return APIntToHexString(AI); } const MCSection * @@ -147,11 +150,16 @@ X86WindowsTargetObjectFile::getSectionForConstant(SectionKind Kind, } else if (const auto *VTy = dyn_cast(Ty)) { uint64_t NumBits = VTy->getBitWidth(); if (NumBits == 128 || NumBits == 256) { - const auto *CDV = cast(C); COMDATSymName = NumBits == 128 ? "__xmm@" : "__ymm@"; - for (int I = CDV->getNumElements() - 1, E = -1; I != E; --I) - COMDATSymName += - scalarConstantToHexString(CDV->getElementAsConstant(I)); + if (const auto *CDV = dyn_cast(C)) { + for (int I = CDV->getNumElements() - 1, E = -1; I != E; --I) + COMDATSymName += + scalarConstantToHexString(CDV->getElementAsConstant(I)); + } else { + const auto *CV = cast(C); + for (int I = CV->getNumOperands() - 1, E = -1; I != E; --I) + COMDATSymName += scalarConstantToHexString(CV->getOperand(I)); + } } } if (!COMDATSymName.empty()) { diff --git a/test/CodeGen/X86/win_cst_pool.ll b/test/CodeGen/X86/win_cst_pool.ll index 7bc046d94e9..e8b853a03da 100644 --- a/test/CodeGen/X86/win_cst_pool.ll +++ b/test/CodeGen/X86/win_cst_pool.ll @@ -47,3 +47,20 @@ define <8 x i16> @vec2() { ; CHECK: vec2: ; CHECK: movaps __xmm@00000001000200030004000500060007(%rip), %xmm0 ; CHECK-NEXT: ret + + +define <4 x float> @undef1() { + ret <4 x float> + +; CHECK: .globl __xmm@00000000000000003f8000003f800000 +; CHECK-NEXT: .section .rdata,"rd",discard,__xmm@00000000000000003f8000003f800000 +; CHECK-NEXT: .align 16 +; CHECK-NEXT: __xmm@00000000000000003f8000003f800000: +; CHECK-NEXT: .long 1065353216 # float 1 +; CHECK-NEXT: .long 1065353216 # float 1 +; CHECK-NEXT: .zero 4 +; CHECK-NEXT: .zero 4 +; CHECK: undef1: +; CHECK: movaps __xmm@00000000000000003f8000003f800000(%rip), %xmm0 +; CHECK-NEXT: ret +}