1 //===--- PatternInit.cpp - Pattern Initialization -------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "PatternInit.h" 10 #include "CodeGenModule.h" 11 #include "llvm/IR/Constant.h" 12 #include "llvm/IR/Type.h" 13 14 llvm::Constant *clang::CodeGen::initializationPatternFor(CodeGenModule &CGM, 15 llvm::Type *Ty) { 16 // The following value is a guaranteed unmappable pointer value and has a 17 // repeated byte-pattern which makes it easier to synthesize. We use it for 18 // pointers as well as integers so that aggregates are likely to be 19 // initialized with this repeated value. 20 constexpr uint64_t LargeValue = 0xAAAAAAAAAAAAAAAAull; 21 // For 32-bit platforms it's a bit trickier because, across systems, only the 22 // zero page can reasonably be expected to be unmapped, and even then we need 23 // a very low address. We use a smaller value, and that value sadly doesn't 24 // have a repeated byte-pattern. We don't use it for integers. 25 constexpr uint32_t SmallValue = 0x000000AA; 26 // Floating-point values are initialized as NaNs because they propagate. Using 27 // a repeated byte pattern means that it will be easier to initialize 28 // all-floating-point aggregates and arrays with memset. Further, aggregates 29 // which mix integral and a few floats might also initialize with memset 30 // followed by a handful of stores for the floats. Using fairly unique NaNs 31 // also means they'll be easier to distinguish in a crash. 32 constexpr bool NegativeNaN = true; 33 constexpr uint64_t NaNPayload = 0xFFFFFFFFFFFFFFFFull; 34 if (Ty->isIntOrIntVectorTy()) { 35 unsigned BitWidth = cast<llvm::IntegerType>( 36 Ty->isVectorTy() ? Ty->getVectorElementType() : Ty) 37 ->getBitWidth(); 38 if (BitWidth <= 64) 39 return llvm::ConstantInt::get(Ty, LargeValue); 40 return llvm::ConstantInt::get( 41 Ty, llvm::APInt::getSplat(BitWidth, llvm::APInt(64, LargeValue))); 42 } 43 if (Ty->isPtrOrPtrVectorTy()) { 44 auto *PtrTy = cast<llvm::PointerType>( 45 Ty->isVectorTy() ? Ty->getVectorElementType() : Ty); 46 unsigned PtrWidth = CGM.getContext().getTargetInfo().getPointerWidth( 47 PtrTy->getAddressSpace()); 48 llvm::Type *IntTy = llvm::IntegerType::get(CGM.getLLVMContext(), PtrWidth); 49 uint64_t IntValue; 50 switch (PtrWidth) { 51 default: 52 llvm_unreachable("pattern initialization of unsupported pointer width"); 53 case 64: 54 IntValue = LargeValue; 55 break; 56 case 32: 57 IntValue = SmallValue; 58 break; 59 } 60 auto *Int = llvm::ConstantInt::get(IntTy, IntValue); 61 return llvm::ConstantExpr::getIntToPtr(Int, PtrTy); 62 } 63 if (Ty->isFPOrFPVectorTy()) { 64 unsigned BitWidth = llvm::APFloat::semanticsSizeInBits( 65 (Ty->isVectorTy() ? Ty->getVectorElementType() : Ty) 66 ->getFltSemantics()); 67 llvm::APInt Payload(64, NaNPayload); 68 if (BitWidth >= 64) 69 Payload = llvm::APInt::getSplat(BitWidth, Payload); 70 return llvm::ConstantFP::getQNaN(Ty, NegativeNaN, &Payload); 71 } 72 if (Ty->isArrayTy()) { 73 // Note: this doesn't touch tail padding (at the end of an object, before 74 // the next array object). It is instead handled by replaceUndef. 75 auto *ArrTy = cast<llvm::ArrayType>(Ty); 76 llvm::SmallVector<llvm::Constant *, 8> Element( 77 ArrTy->getNumElements(), 78 initializationPatternFor(CGM, ArrTy->getElementType())); 79 return llvm::ConstantArray::get(ArrTy, Element); 80 } 81 82 // Note: this doesn't touch struct padding. It will initialize as much union 83 // padding as is required for the largest type in the union. Padding is 84 // instead handled by replaceUndef. Stores to structs with volatile members 85 // don't have a volatile qualifier when initialized according to C++. This is 86 // fine because stack-based volatiles don't really have volatile semantics 87 // anyways, and the initialization shouldn't be observable. 88 auto *StructTy = cast<llvm::StructType>(Ty); 89 llvm::SmallVector<llvm::Constant *, 8> Struct(StructTy->getNumElements()); 90 for (unsigned El = 0; El != Struct.size(); ++El) 91 Struct[El] = initializationPatternFor(CGM, StructTy->getElementType(El)); 92 return llvm::ConstantStruct::get(StructTy, Struct); 93 } 94