14d0b32cdSDimitry Andric //===-- X86ShuffleDecodeConstantPool.cpp - X86 shuffle decode -------------===// 24d0b32cdSDimitry Andric // 34d0b32cdSDimitry Andric // The LLVM Compiler Infrastructure 44d0b32cdSDimitry Andric // 54d0b32cdSDimitry Andric // This file is distributed under the University of Illinois Open Source 64d0b32cdSDimitry Andric // License. See LICENSE.TXT for details. 74d0b32cdSDimitry Andric // 84d0b32cdSDimitry Andric //===----------------------------------------------------------------------===// 94d0b32cdSDimitry Andric // 104d0b32cdSDimitry Andric // Define several functions to decode x86 specific shuffle semantics using 114d0b32cdSDimitry Andric // constants from the constant pool. 124d0b32cdSDimitry Andric // 134d0b32cdSDimitry Andric //===----------------------------------------------------------------------===// 144d0b32cdSDimitry Andric 154d0b32cdSDimitry Andric #include "X86ShuffleDecodeConstantPool.h" 164d0b32cdSDimitry Andric #include "Utils/X86ShuffleDecode.h" 17d88c1a5aSDimitry Andric #include "llvm/ADT/SmallBitVector.h" 184d0b32cdSDimitry Andric #include "llvm/CodeGen/MachineValueType.h" 194d0b32cdSDimitry Andric #include "llvm/IR/Constants.h" 204d0b32cdSDimitry Andric 214d0b32cdSDimitry Andric //===----------------------------------------------------------------------===// 224d0b32cdSDimitry Andric // Vector Mask Decoding 234d0b32cdSDimitry Andric //===----------------------------------------------------------------------===// 244d0b32cdSDimitry Andric 254d0b32cdSDimitry Andric namespace llvm { 264d0b32cdSDimitry Andric 27d88c1a5aSDimitry Andric static bool extractConstantMask(const Constant *C, unsigned MaskEltSizeInBits, 28d88c1a5aSDimitry Andric SmallBitVector &UndefElts, 29d88c1a5aSDimitry Andric SmallVectorImpl<uint64_t> &RawMask) { 30d88c1a5aSDimitry Andric // It is not an error for shuffle masks to not be a vector of 31d88c1a5aSDimitry Andric // MaskEltSizeInBits because the constant pool uniques constants by their 32d88c1a5aSDimitry Andric // bit representation. 334d0b32cdSDimitry Andric // e.g. the following take up the same space in the constant pool: 344d0b32cdSDimitry Andric // i128 -170141183420855150465331762880109871104 354d0b32cdSDimitry Andric // 364d0b32cdSDimitry Andric // <2 x i64> <i64 -9223372034707292160, i64 -9223372034707292160> 374d0b32cdSDimitry Andric // 384d0b32cdSDimitry Andric // <4 x i32> <i32 -2147483648, i32 -2147483648, 394d0b32cdSDimitry Andric // i32 -2147483648, i32 -2147483648> 40d88c1a5aSDimitry Andric Type *CstTy = C->getType(); 41d88c1a5aSDimitry Andric if (!CstTy->isVectorTy()) 42d88c1a5aSDimitry Andric return false; 434d0b32cdSDimitry Andric 44d88c1a5aSDimitry Andric Type *CstEltTy = CstTy->getVectorElementType(); 45d88c1a5aSDimitry Andric if (!CstEltTy->isIntegerTy()) 46d88c1a5aSDimitry Andric return false; 474d0b32cdSDimitry Andric 48d88c1a5aSDimitry Andric unsigned CstSizeInBits = CstTy->getPrimitiveSizeInBits(); 49d88c1a5aSDimitry Andric unsigned CstEltSizeInBits = CstTy->getScalarSizeInBits(); 50d88c1a5aSDimitry Andric unsigned NumCstElts = CstTy->getVectorNumElements(); 514d0b32cdSDimitry Andric 52d88c1a5aSDimitry Andric // Extract all the undef/constant element data and pack into single bitsets. 53d88c1a5aSDimitry Andric APInt UndefBits(CstSizeInBits, 0); 54d88c1a5aSDimitry Andric APInt MaskBits(CstSizeInBits, 0); 55d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumCstElts; ++i) { 564d0b32cdSDimitry Andric Constant *COp = C->getAggregateElement(i); 57d88c1a5aSDimitry Andric if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp))) 58d88c1a5aSDimitry Andric return false; 59d88c1a5aSDimitry Andric 60d88c1a5aSDimitry Andric if (isa<UndefValue>(COp)) { 61d88c1a5aSDimitry Andric APInt EltUndef = APInt::getLowBitsSet(CstSizeInBits, CstEltSizeInBits); 62d88c1a5aSDimitry Andric UndefBits |= EltUndef.shl(i * CstEltSizeInBits); 634d0b32cdSDimitry Andric continue; 644d0b32cdSDimitry Andric } 653ca95b02SDimitry Andric 66d88c1a5aSDimitry Andric APInt EltBits = cast<ConstantInt>(COp)->getValue(); 67d88c1a5aSDimitry Andric EltBits = EltBits.zextOrTrunc(CstSizeInBits); 68d88c1a5aSDimitry Andric MaskBits |= EltBits.shl(i * CstEltSizeInBits); 69d88c1a5aSDimitry Andric } 703ca95b02SDimitry Andric 71d88c1a5aSDimitry Andric // Now extract the undef/constant bit data into the raw shuffle masks. 72d88c1a5aSDimitry Andric assert((CstSizeInBits % MaskEltSizeInBits) == 0 && 73d88c1a5aSDimitry Andric "Unaligned shuffle mask size"); 743ca95b02SDimitry Andric 75d88c1a5aSDimitry Andric unsigned NumMaskElts = CstSizeInBits / MaskEltSizeInBits; 76d88c1a5aSDimitry Andric UndefElts = SmallBitVector(NumMaskElts, false); 77d88c1a5aSDimitry Andric RawMask.resize(NumMaskElts, 0); 78d88c1a5aSDimitry Andric 79d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumMaskElts; ++i) { 80d88c1a5aSDimitry Andric APInt EltUndef = UndefBits.lshr(i * MaskEltSizeInBits); 81d88c1a5aSDimitry Andric EltUndef = EltUndef.zextOrTrunc(MaskEltSizeInBits); 82d88c1a5aSDimitry Andric 83d88c1a5aSDimitry Andric // Only treat the element as UNDEF if all bits are UNDEF, otherwise 84d88c1a5aSDimitry Andric // treat it as zero. 85d88c1a5aSDimitry Andric if (EltUndef.isAllOnesValue()) { 86d88c1a5aSDimitry Andric UndefElts[i] = true; 87d88c1a5aSDimitry Andric RawMask[i] = 0; 88d88c1a5aSDimitry Andric continue; 89d88c1a5aSDimitry Andric } 90d88c1a5aSDimitry Andric 91d88c1a5aSDimitry Andric APInt EltBits = MaskBits.lshr(i * MaskEltSizeInBits); 92d88c1a5aSDimitry Andric EltBits = EltBits.zextOrTrunc(MaskEltSizeInBits); 93d88c1a5aSDimitry Andric RawMask[i] = EltBits.getZExtValue(); 94d88c1a5aSDimitry Andric } 95d88c1a5aSDimitry Andric 96d88c1a5aSDimitry Andric return true; 97d88c1a5aSDimitry Andric } 98d88c1a5aSDimitry Andric 99d88c1a5aSDimitry Andric void DecodePSHUFBMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) { 100d88c1a5aSDimitry Andric Type *MaskTy = C->getType(); 101d88c1a5aSDimitry Andric unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 102d88c1a5aSDimitry Andric (void)MaskTySize; 103d88c1a5aSDimitry Andric assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 104d88c1a5aSDimitry Andric "Unexpected vector size."); 105d88c1a5aSDimitry Andric 106d88c1a5aSDimitry Andric // The shuffle mask requires a byte vector. 107d88c1a5aSDimitry Andric SmallBitVector UndefElts; 108d88c1a5aSDimitry Andric SmallVector<uint64_t, 32> RawMask; 109d88c1a5aSDimitry Andric if (!extractConstantMask(C, 8, UndefElts, RawMask)) 110d88c1a5aSDimitry Andric return; 111d88c1a5aSDimitry Andric 112d88c1a5aSDimitry Andric unsigned NumElts = RawMask.size(); 113d88c1a5aSDimitry Andric assert((NumElts == 16 || NumElts == 32 || NumElts == 64) && 114d88c1a5aSDimitry Andric "Unexpected number of vector elements."); 115d88c1a5aSDimitry Andric 116d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 117d88c1a5aSDimitry Andric if (UndefElts[i]) { 118d88c1a5aSDimitry Andric ShuffleMask.push_back(SM_SentinelUndef); 119d88c1a5aSDimitry Andric continue; 120d88c1a5aSDimitry Andric } 121d88c1a5aSDimitry Andric 122d88c1a5aSDimitry Andric uint64_t Element = RawMask[i]; 1234d0b32cdSDimitry Andric // If the high bit (7) of the byte is set, the element is zeroed. 1244d0b32cdSDimitry Andric if (Element & (1 << 7)) 1254d0b32cdSDimitry Andric ShuffleMask.push_back(SM_SentinelZero); 1264d0b32cdSDimitry Andric else { 127d88c1a5aSDimitry Andric // For AVX vectors with 32 bytes the base of the shuffle is the 16-byte 128d88c1a5aSDimitry Andric // lane of the vector we're inside. 129d88c1a5aSDimitry Andric unsigned Base = i & ~0xf; 130d88c1a5aSDimitry Andric 1314d0b32cdSDimitry Andric // Only the least significant 4 bits of the byte are used. 1324d0b32cdSDimitry Andric int Index = Base + (Element & 0xf); 1334d0b32cdSDimitry Andric ShuffleMask.push_back(Index); 1344d0b32cdSDimitry Andric } 1354d0b32cdSDimitry Andric } 1364d0b32cdSDimitry Andric } 1373ca95b02SDimitry Andric 1384d0b32cdSDimitry Andric void DecodeVPERMILPMask(const Constant *C, unsigned ElSize, 1394d0b32cdSDimitry Andric SmallVectorImpl<int> &ShuffleMask) { 1404d0b32cdSDimitry Andric Type *MaskTy = C->getType(); 1413ca95b02SDimitry Andric unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 142d88c1a5aSDimitry Andric (void)MaskTySize; 143d88c1a5aSDimitry Andric assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 144d88c1a5aSDimitry Andric "Unexpected vector size."); 145d88c1a5aSDimitry Andric assert((ElSize == 32 || ElSize == 64) && "Unexpected vector element size."); 146d88c1a5aSDimitry Andric 147d88c1a5aSDimitry Andric // The shuffle mask requires elements the same size as the target. 148d88c1a5aSDimitry Andric SmallBitVector UndefElts; 149d88c1a5aSDimitry Andric SmallVector<uint64_t, 8> RawMask; 150d88c1a5aSDimitry Andric if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 1514d0b32cdSDimitry Andric return; 1524d0b32cdSDimitry Andric 153d88c1a5aSDimitry Andric unsigned NumElts = RawMask.size(); 154d88c1a5aSDimitry Andric unsigned NumEltsPerLane = 128 / ElSize; 155d88c1a5aSDimitry Andric assert((NumElts == 2 || NumElts == 4 || NumElts == 8 || NumElts == 16) && 1564d0b32cdSDimitry Andric "Unexpected number of vector elements."); 1574d0b32cdSDimitry Andric 158d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 159d88c1a5aSDimitry Andric if (UndefElts[i]) { 1604d0b32cdSDimitry Andric ShuffleMask.push_back(SM_SentinelUndef); 1614d0b32cdSDimitry Andric continue; 1624d0b32cdSDimitry Andric } 163d88c1a5aSDimitry Andric 164d88c1a5aSDimitry Andric int Index = i & ~(NumEltsPerLane - 1); 165d88c1a5aSDimitry Andric uint64_t Element = RawMask[i]; 1664d0b32cdSDimitry Andric if (ElSize == 64) 1674d0b32cdSDimitry Andric Index += (Element >> 1) & 0x1; 1684d0b32cdSDimitry Andric else 1694d0b32cdSDimitry Andric Index += Element & 0x3; 170d88c1a5aSDimitry Andric 1714d0b32cdSDimitry Andric ShuffleMask.push_back(Index); 1724d0b32cdSDimitry Andric } 1734d0b32cdSDimitry Andric } 1744d0b32cdSDimitry Andric 1753ca95b02SDimitry Andric void DecodeVPERMIL2PMask(const Constant *C, unsigned M2Z, unsigned ElSize, 1763ca95b02SDimitry Andric SmallVectorImpl<int> &ShuffleMask) { 1773ca95b02SDimitry Andric Type *MaskTy = C->getType(); 1783ca95b02SDimitry Andric unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 179d88c1a5aSDimitry Andric (void)MaskTySize; 180d88c1a5aSDimitry Andric assert((MaskTySize == 128 || MaskTySize == 256) && "Unexpected vector size."); 181d88c1a5aSDimitry Andric 182d88c1a5aSDimitry Andric // The shuffle mask requires elements the same size as the target. 183d88c1a5aSDimitry Andric SmallBitVector UndefElts; 184d88c1a5aSDimitry Andric SmallVector<uint64_t, 8> RawMask; 185d88c1a5aSDimitry Andric if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 1863ca95b02SDimitry Andric return; 1873ca95b02SDimitry Andric 188d88c1a5aSDimitry Andric unsigned NumElts = RawMask.size(); 189d88c1a5aSDimitry Andric unsigned NumEltsPerLane = 128 / ElSize; 190d88c1a5aSDimitry Andric assert((NumElts == 2 || NumElts == 4 || NumElts == 8) && 1913ca95b02SDimitry Andric "Unexpected number of vector elements."); 1923ca95b02SDimitry Andric 193d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 194d88c1a5aSDimitry Andric if (UndefElts[i]) { 1953ca95b02SDimitry Andric ShuffleMask.push_back(SM_SentinelUndef); 1963ca95b02SDimitry Andric continue; 1973ca95b02SDimitry Andric } 1983ca95b02SDimitry Andric 1993ca95b02SDimitry Andric // VPERMIL2 Operation. 2003ca95b02SDimitry Andric // Bits[3] - Match Bit. 2013ca95b02SDimitry Andric // Bits[2:1] - (Per Lane) PD Shuffle Mask. 2023ca95b02SDimitry Andric // Bits[2:0] - (Per Lane) PS Shuffle Mask. 203d88c1a5aSDimitry Andric uint64_t Selector = RawMask[i]; 2043ca95b02SDimitry Andric unsigned MatchBit = (Selector >> 3) & 0x1; 2053ca95b02SDimitry Andric 2063ca95b02SDimitry Andric // M2Z[0:1] MatchBit 2073ca95b02SDimitry Andric // 0Xb X Source selected by Selector index. 2083ca95b02SDimitry Andric // 10b 0 Source selected by Selector index. 2093ca95b02SDimitry Andric // 10b 1 Zero. 2103ca95b02SDimitry Andric // 11b 0 Zero. 2113ca95b02SDimitry Andric // 11b 1 Source selected by Selector index. 2123ca95b02SDimitry Andric if ((M2Z & 0x2) != 0u && MatchBit != (M2Z & 0x1)) { 2133ca95b02SDimitry Andric ShuffleMask.push_back(SM_SentinelZero); 2143ca95b02SDimitry Andric continue; 2153ca95b02SDimitry Andric } 2163ca95b02SDimitry Andric 217d88c1a5aSDimitry Andric int Index = i & ~(NumEltsPerLane - 1); 2183ca95b02SDimitry Andric if (ElSize == 64) 2193ca95b02SDimitry Andric Index += (Selector >> 1) & 0x1; 2203ca95b02SDimitry Andric else 2213ca95b02SDimitry Andric Index += Selector & 0x3; 2223ca95b02SDimitry Andric 2233ca95b02SDimitry Andric int Src = (Selector >> 2) & 0x1; 224d88c1a5aSDimitry Andric Index += Src * NumElts; 2253ca95b02SDimitry Andric ShuffleMask.push_back(Index); 2263ca95b02SDimitry Andric } 2273ca95b02SDimitry Andric } 2283ca95b02SDimitry Andric 2293ca95b02SDimitry Andric void DecodeVPPERMMask(const Constant *C, SmallVectorImpl<int> &ShuffleMask) { 230d88c1a5aSDimitry Andric assert(C->getType()->getPrimitiveSizeInBits() == 128 && 231d88c1a5aSDimitry Andric "Unexpected vector size."); 2323ca95b02SDimitry Andric 233d88c1a5aSDimitry Andric // The shuffle mask requires a byte vector. 234d88c1a5aSDimitry Andric SmallBitVector UndefElts; 235d88c1a5aSDimitry Andric SmallVector<uint64_t, 32> RawMask; 236d88c1a5aSDimitry Andric if (!extractConstantMask(C, 8, UndefElts, RawMask)) 2373ca95b02SDimitry Andric return; 2383ca95b02SDimitry Andric 239d88c1a5aSDimitry Andric unsigned NumElts = RawMask.size(); 240d88c1a5aSDimitry Andric assert(NumElts == 16 && "Unexpected number of vector elements."); 2413ca95b02SDimitry Andric 242d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 243d88c1a5aSDimitry Andric if (UndefElts[i]) { 244d88c1a5aSDimitry Andric ShuffleMask.push_back(SM_SentinelUndef); 2453ca95b02SDimitry Andric continue; 2463ca95b02SDimitry Andric } 2473ca95b02SDimitry Andric 2483ca95b02SDimitry Andric // VPPERM Operation 2493ca95b02SDimitry Andric // Bits[4:0] - Byte Index (0 - 31) 2503ca95b02SDimitry Andric // Bits[7:5] - Permute Operation 2513ca95b02SDimitry Andric // 2523ca95b02SDimitry Andric // Permute Operation: 2533ca95b02SDimitry Andric // 0 - Source byte (no logical operation). 2543ca95b02SDimitry Andric // 1 - Invert source byte. 2553ca95b02SDimitry Andric // 2 - Bit reverse of source byte. 2563ca95b02SDimitry Andric // 3 - Bit reverse of inverted source byte. 2573ca95b02SDimitry Andric // 4 - 00h (zero - fill). 2583ca95b02SDimitry Andric // 5 - FFh (ones - fill). 2593ca95b02SDimitry Andric // 6 - Most significant bit of source byte replicated in all bit positions. 260d88c1a5aSDimitry Andric // 7 - Invert most significant bit of source byte and replicate in all bit 261d88c1a5aSDimitry Andric // positions. 262d88c1a5aSDimitry Andric uint64_t Element = RawMask[i]; 263d88c1a5aSDimitry Andric uint64_t Index = Element & 0x1F; 264d88c1a5aSDimitry Andric uint64_t PermuteOp = (Element >> 5) & 0x7; 2653ca95b02SDimitry Andric 2663ca95b02SDimitry Andric if (PermuteOp == 4) { 2673ca95b02SDimitry Andric ShuffleMask.push_back(SM_SentinelZero); 2683ca95b02SDimitry Andric continue; 2693ca95b02SDimitry Andric } 2703ca95b02SDimitry Andric if (PermuteOp != 0) { 2713ca95b02SDimitry Andric ShuffleMask.clear(); 2723ca95b02SDimitry Andric return; 2733ca95b02SDimitry Andric } 274d88c1a5aSDimitry Andric ShuffleMask.push_back((int)Index); 2753ca95b02SDimitry Andric } 2763ca95b02SDimitry Andric } 2773ca95b02SDimitry Andric 278d88c1a5aSDimitry Andric void DecodeVPERMVMask(const Constant *C, unsigned ElSize, 2794d0b32cdSDimitry Andric SmallVectorImpl<int> &ShuffleMask) { 2804d0b32cdSDimitry Andric Type *MaskTy = C->getType(); 281d88c1a5aSDimitry Andric unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 282d88c1a5aSDimitry Andric (void)MaskTySize; 283d88c1a5aSDimitry Andric assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 284d88c1a5aSDimitry Andric "Unexpected vector size."); 285d88c1a5aSDimitry Andric assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) && 286d88c1a5aSDimitry Andric "Unexpected vector element size."); 287d88c1a5aSDimitry Andric 288d88c1a5aSDimitry Andric // The shuffle mask requires elements the same size as the target. 289d88c1a5aSDimitry Andric SmallBitVector UndefElts; 290d88c1a5aSDimitry Andric SmallVector<uint64_t, 8> RawMask; 291d88c1a5aSDimitry Andric if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 2924d0b32cdSDimitry Andric return; 293d88c1a5aSDimitry Andric 294d88c1a5aSDimitry Andric unsigned NumElts = RawMask.size(); 295d88c1a5aSDimitry Andric 296d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 297d88c1a5aSDimitry Andric if (UndefElts[i]) { 2984d0b32cdSDimitry Andric ShuffleMask.push_back(SM_SentinelUndef); 299d88c1a5aSDimitry Andric continue; 3004d0b32cdSDimitry Andric } 301d88c1a5aSDimitry Andric int Index = RawMask[i] & (NumElts - 1); 302d88c1a5aSDimitry Andric ShuffleMask.push_back(Index); 3034d0b32cdSDimitry Andric } 3044d0b32cdSDimitry Andric } 3054d0b32cdSDimitry Andric 306d88c1a5aSDimitry Andric void DecodeVPERMV3Mask(const Constant *C, unsigned ElSize, 3074d0b32cdSDimitry Andric SmallVectorImpl<int> &ShuffleMask) { 3084d0b32cdSDimitry Andric Type *MaskTy = C->getType(); 309d88c1a5aSDimitry Andric unsigned MaskTySize = MaskTy->getPrimitiveSizeInBits(); 310d88c1a5aSDimitry Andric (void)MaskTySize; 311d88c1a5aSDimitry Andric assert((MaskTySize == 128 || MaskTySize == 256 || MaskTySize == 512) && 312d88c1a5aSDimitry Andric "Unexpected vector size."); 313d88c1a5aSDimitry Andric assert((ElSize == 8 || ElSize == 16 || ElSize == 32 || ElSize == 64) && 314d88c1a5aSDimitry Andric "Unexpected vector element size."); 315d88c1a5aSDimitry Andric 316d88c1a5aSDimitry Andric // The shuffle mask requires elements the same size as the target. 317d88c1a5aSDimitry Andric SmallBitVector UndefElts; 318d88c1a5aSDimitry Andric SmallVector<uint64_t, 8> RawMask; 319d88c1a5aSDimitry Andric if (!extractConstantMask(C, ElSize, UndefElts, RawMask)) 3204d0b32cdSDimitry Andric return; 321d88c1a5aSDimitry Andric 322d88c1a5aSDimitry Andric unsigned NumElts = RawMask.size(); 323d88c1a5aSDimitry Andric 324d88c1a5aSDimitry Andric for (unsigned i = 0; i != NumElts; ++i) { 325d88c1a5aSDimitry Andric if (UndefElts[i]) { 3264d0b32cdSDimitry Andric ShuffleMask.push_back(SM_SentinelUndef); 327d88c1a5aSDimitry Andric continue; 3284d0b32cdSDimitry Andric } 329d88c1a5aSDimitry Andric int Index = RawMask[i] & (NumElts*2 - 1); 330d88c1a5aSDimitry Andric ShuffleMask.push_back(Index); 3314d0b32cdSDimitry Andric } 3324d0b32cdSDimitry Andric } 3334d0b32cdSDimitry Andric } // llvm namespace 334