Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -1812,6 +1812,9 @@ must be a multiple of 8-bits. If omitted, the natural stack alignment defaults to "unspecified", which does not prevent any alignment promotions. +``A
::`` This specifies the *size* of a pointer and its ```` and ````\erred alignments for address space ``n``. All sizes are in @@ -7149,7 +7152,7 @@ :: - = alloca [inalloca] [, ] [, align ] ; yields type*:result + = alloca [inalloca] [, ] [, align ] [, addrspace()] ; yields type addrspace(num)*:result Overview: """"""""" @@ -7157,7 +7160,7 @@ The '``alloca``' instruction allocates memory on the stack frame of the currently executing function, to be automatically released when this function returns to its caller. The object is always allocated in the -generic address space (address space zero). +address space for allocas indicated in the datalayout. Arguments: """""""""" Index: include/llvm/IR/DataLayout.h =================================================================== --- include/llvm/IR/DataLayout.h +++ include/llvm/IR/DataLayout.h @@ -104,6 +104,7 @@ /// Defaults to false. bool BigEndian; + unsigned StackAddrSpace; unsigned StackNaturalAlign; enum ManglingModeT { @@ -199,6 +200,7 @@ clear(); StringRepresentation = DL.StringRepresentation; BigEndian = DL.isBigEndian(); + StackAddrSpace = DL.StackAddrSpace; StackNaturalAlign = DL.StackNaturalAlign; ManglingMode = DL.ManglingMode; LegalIntWidths = DL.LegalIntWidths; @@ -254,6 +256,7 @@ } unsigned getStackAlignment() const { return StackNaturalAlign; } + unsigned getStackAddrSpace() const { return StackAddrSpace; } bool hasMicrosoftFastStdCallMangling() const { return ManglingMode == MM_WinCOFFX86; Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -1089,9 +1089,14 @@ // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// - AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr, - const Twine &Name = "") { - return Insert(new AllocaInst(Ty, ArraySize), Name); + AllocaInst *CreateAlloca(Type *Ty, unsigned AddrSpace, + Value *ArraySize = nullptr, const Twine &Name = "") { + return Insert(new AllocaInst(Ty, AddrSpace, ArraySize), Name); + } + + AllocaInst *CreateAlloca(const DataLayout &DL, Type *Ty, + Value *ArraySize = nullptr, const Twine &Name = "") { + return Insert(new AllocaInst(Ty, DL.getStackAddrSpace(), ArraySize), Name); } // \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of // converting the string to 'bool' for the isVolatile parameter. Index: include/llvm/IR/Instructions.h =================================================================== --- include/llvm/IR/Instructions.h +++ include/llvm/IR/Instructions.h @@ -67,18 +67,21 @@ AllocaInst *cloneImpl() const; public: - explicit AllocaInst(Type *Ty, Value *ArraySize = nullptr, + explicit AllocaInst(Type *Ty, unsigned AddrSpace, + Value *ArraySize = nullptr, const Twine &Name = "", Instruction *InsertBefore = nullptr); - AllocaInst(Type *Ty, Value *ArraySize, + AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, const Twine &Name, BasicBlock *InsertAtEnd); - AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore = nullptr); - AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); + AllocaInst(Type *Ty, unsigned AddrSpace, + const Twine &Name, Instruction *InsertBefore = nullptr); + AllocaInst(Type *Ty, unsigned AddrSpace, + const Twine &Name, BasicBlock *InsertAtEnd); - AllocaInst(Type *Ty, Value *ArraySize, unsigned Align, + AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align, const Twine &Name = "", Instruction *InsertBefore = nullptr); - AllocaInst(Type *Ty, Value *ArraySize, unsigned Align, + AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, unsigned Align, const Twine &Name, BasicBlock *InsertAtEnd); // Out of line virtual method, so the vtable, etc. has a home. Index: lib/AsmParser/LLParser.h =================================================================== --- lib/AsmParser/LLParser.h +++ lib/AsmParser/LLParser.h @@ -242,6 +242,8 @@ bool ParseOrdering(AtomicOrdering &Ordering); bool ParseOptionalStackAlignment(unsigned &Alignment); bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma); + bool ParseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc, + bool &AteExtraComma); bool ParseOptionalCommaInAlloca(bool &IsInAlloca); bool parseAllocSizeArguments(unsigned &ElemSizeArg, Optional &HowManyArg); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -1855,6 +1855,34 @@ return false; } +/// ParseOptionalCommaAddrSpace +/// ::= +/// ::= ',' addrspace(1) +/// +/// This returns with AteExtraComma set to true if it ate an excess comma at the +/// end. +bool LLParser::ParseOptionalCommaAddrSpace(unsigned &AddrSpace, + LocTy &Loc, + bool &AteExtraComma) { + AteExtraComma = false; + while (EatIfPresent(lltok::comma)) { + // Metadata at the end is an early exit. + if (Lex.getKind() == lltok::MetadataVar) { + AteExtraComma = true; + return false; + } + + Loc = Lex.getLoc(); + if (Lex.getKind() != lltok::kw_addrspace) + return Error(Lex.getLoc(), "expected metadata or 'addrspace'"); + + if (ParseOptionalAddrSpace(AddrSpace)) + return true; + } + + return false; +} + bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg, Optional &HowManyArg) { Lex.Lex(); @@ -6040,8 +6068,9 @@ /// (',' 'align' i32)? int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { Value *Size = nullptr; - LocTy SizeLoc, TyLoc; + LocTy SizeLoc, TyLoc, ASLoc; unsigned Alignment = 0; + unsigned AddrSpace = 0; Type *Ty = nullptr; bool IsInAlloca = EatIfPresent(lltok::kw_inalloca); @@ -6055,12 +6084,21 @@ bool AteExtraComma = false; if (EatIfPresent(lltok::comma)) { if (Lex.getKind() == lltok::kw_align) { - if (ParseOptionalAlignment(Alignment)) return true; + if (ParseOptionalAlignment(Alignment)) + return true; + if (ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma)) + return true; + } else if (Lex.getKind() == lltok::kw_addrspace) { + ASLoc = Lex.getLoc(); + if (ParseOptionalAddrSpace(AddrSpace)) + return true; } else if (Lex.getKind() == lltok::MetadataVar) { AteExtraComma = true; } else { if (ParseTypeAndValue(Size, SizeLoc, PFS) || - ParseOptionalCommaAlign(Alignment, AteExtraComma)) + ParseOptionalCommaAlign(Alignment, AteExtraComma) || + (!AteExtraComma && + ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma))) return true; } } @@ -6068,7 +6106,14 @@ if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - AllocaInst *AI = new AllocaInst(Ty, Size, Alignment); + const DataLayout &DL = M->getDataLayout(); + unsigned AS = DL.getStackAddrSpace(); + if (AS != AddrSpace) { + // TODO: In the future it should be possible to specify addrspace per-alloca. + return Error(ASLoc, "address space must match datalayout"); + } + + AllocaInst *AI = new AllocaInst(Ty, AS, Size, Alignment); AI->setUsedWithInAlloca(IsInAlloca); AI->setSwiftError(IsSwiftError); Inst = AI; Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -4017,7 +4017,12 @@ } if (!Ty || !Size) return error("Invalid record"); - AllocaInst *AI = new AllocaInst(Ty, Size, Align); + + // FIXME: Make this an optional field. + const DataLayout &DL = TheModule->getDataLayout(); + unsigned AS = DL.getStackAddrSpace(); + + AllocaInst *AI = new AllocaInst(Ty, AS, Size, Align); AI->setUsedWithInAlloca(InAlloca); AI->setSwiftError(SwiftError); I = AI; Index: lib/CodeGen/AtomicExpandPass.cpp =================================================================== --- lib/CodeGen/AtomicExpandPass.cpp +++ lib/CodeGen/AtomicExpandPass.cpp @@ -1547,7 +1547,7 @@ // 'expected' argument, if present. if (CASExpected) { - AllocaCASExpected = AllocaBuilder.CreateAlloca(CASExpected->getType()); + AllocaCASExpected = AllocaBuilder.CreateAlloca(DL, CASExpected->getType()); AllocaCASExpected->setAlignment(AllocaAlignment); AllocaCASExpected_i8 = Builder.CreateBitCast(AllocaCASExpected, Type::getInt8PtrTy(Ctx)); @@ -1563,7 +1563,7 @@ Builder.CreateBitOrPointerCast(ValueOperand, SizedIntTy); Args.push_back(IntValue); } else { - AllocaValue = AllocaBuilder.CreateAlloca(ValueOperand->getType()); + AllocaValue = AllocaBuilder.CreateAlloca(DL, ValueOperand->getType()); AllocaValue->setAlignment(AllocaAlignment); AllocaValue_i8 = Builder.CreateBitCast(AllocaValue, Type::getInt8PtrTy(Ctx)); @@ -1575,7 +1575,7 @@ // 'ret' argument. if (!CASExpected && HasResult && !UseSizedLibcall) { - AllocaResult = AllocaBuilder.CreateAlloca(I->getType()); + AllocaResult = AllocaBuilder.CreateAlloca(DL, I->getType()); AllocaResult->setAlignment(AllocaAlignment); AllocaResult_i8 = Builder.CreateBitCast(AllocaResult, Type::getInt8PtrTy(Ctx)); Index: lib/CodeGen/SafeStack.cpp =================================================================== --- lib/CodeGen/SafeStack.cpp +++ lib/CodeGen/SafeStack.cpp @@ -185,7 +185,7 @@ bool doInitialization(Module &M) override { DL = &M.getDataLayout(); - StackPtrTy = Type::getInt8PtrTy(M.getContext()); + StackPtrTy = Type::getInt8PtrTy(M.getContext(), DL->getStackAddrSpace()); IntPtrTy = DL->getIntPtrType(M.getContext()); Int32Ty = Type::getInt32Ty(M.getContext()); Int8Ty = Type::getInt8Ty(M.getContext()); @@ -418,7 +418,7 @@ if (NeedDynamicTop) { // If we also have dynamic alloca's, the stack pointer value changes // throughout the function. For now we store it in an alloca. - DynamicTop = IRB.CreateAlloca(StackPtrTy, /*ArraySize=*/nullptr, + DynamicTop = IRB.CreateAlloca(*DL, StackPtrTy, /*ArraySize=*/nullptr, "unsafe_stack_dynamic_ptr"); IRB.CreateStore(StaticTop, DynamicTop); } @@ -750,7 +750,7 @@ F.hasFnAttribute(Attribute::StackProtectStrong) || F.hasFnAttribute(Attribute::StackProtectReq)) { Value *StackGuard = getStackGuard(IRB, F); - StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr); + StackGuardSlot = IRB.CreateAlloca(*DL, StackPtrTy, nullptr); IRB.CreateStore(StackGuard, StackGuardSlot); for (ReturnInst *RI : Returns) { Index: lib/CodeGen/ShadowStackGCLowering.cpp =================================================================== --- lib/CodeGen/ShadowStackGCLowering.cpp +++ lib/CodeGen/ShadowStackGCLowering.cpp @@ -288,8 +288,9 @@ BasicBlock::iterator IP = F.getEntryBlock().begin(); IRBuilder<> AtEntry(IP->getParent(), IP); + const DataLayout &DL = F.getParent()->getDataLayout(); Instruction *StackEntry = - AtEntry.CreateAlloca(ConcreteStackEntryTy, nullptr, "gc_frame"); + AtEntry.CreateAlloca(DL, ConcreteStackEntryTy, nullptr, "gc_frame"); while (isa(IP)) ++IP; Index: lib/CodeGen/SjLjEHPrepare.cpp =================================================================== --- lib/CodeGen/SjLjEHPrepare.cpp +++ lib/CodeGen/SjLjEHPrepare.cpp @@ -175,8 +175,8 @@ // because the value needs to be added to the global context list. auto &DL = F.getParent()->getDataLayout(); unsigned Align = DL.getPrefTypeAlignment(FunctionContextTy); - FuncCtx = new AllocaInst(FunctionContextTy, nullptr, Align, "fn_context", - &EntryBB->front()); + FuncCtx = new AllocaInst(FunctionContextTy, DL.getStackAddrSpace(), + nullptr, Align, "fn_context", &EntryBB->front()); // Fill in the function context structure. for (LandingPadInst *LPI : LPads) { Index: lib/CodeGen/StackProtector.cpp =================================================================== --- lib/CodeGen/StackProtector.cpp +++ lib/CodeGen/StackProtector.cpp @@ -351,7 +351,7 @@ bool SupportsSelectionDAGSP = false; IRBuilder<> B(&F->getEntryBlock().front()); PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); - AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot"); + AI = B.CreateAlloca(M->getDataLayout(), PtrTy, nullptr, "StackGuardSlot"); Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP); B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector), Index: lib/CodeGen/WinEHPrepare.cpp =================================================================== --- lib/CodeGen/WinEHPrepare.cpp +++ lib/CodeGen/WinEHPrepare.cpp @@ -86,6 +86,7 @@ // All fields are reset by runOnFunction. EHPersonality Personality = EHPersonality::Unknown; + const DataLayout *DL = nullptr; DenseMap BlockColors; MapVector> FuncletBlocks; }; @@ -111,6 +112,7 @@ if (!isFuncletEHPersonality(Personality)) return false; + DL = &Fn.getParent()->getDataLayout(); return prepareExplicitEH(Fn); } @@ -1070,7 +1072,7 @@ if (!isa(EHPad)) { // If the EHPad isn't a terminator, then we can insert a load in this block // that will dominate all uses. - SpillSlot = new AllocaInst(PN->getType(), nullptr, + SpillSlot = new AllocaInst(PN->getType(), DL->getStackAddrSpace(), nullptr, Twine(PN->getName(), ".wineh.spillslot"), &F.getEntryBlock().front()); Value *V = new LoadInst(SpillSlot, Twine(PN->getName(), ".wineh.reload"), @@ -1157,7 +1159,7 @@ Function &F) { // Lazilly create the spill slot. if (!SpillSlot) - SpillSlot = new AllocaInst(V->getType(), nullptr, + SpillSlot = new AllocaInst(V->getType(), DL->getStackAddrSpace(), nullptr, Twine(V->getName(), ".wineh.spillslot"), &F.getEntryBlock().front()); Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -3114,6 +3114,12 @@ if (AI->getAlignment()) { Out << ", align " << AI->getAlignment(); } + + unsigned AddrSpace = AI->getType()->getAddressSpace(); + if (AddrSpace != 0) { + Out << ", addrspace(" << AddrSpace << ')'; + } + } else if (isa(I)) { if (Operand) { Out << ' '; Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -2698,12 +2698,17 @@ LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { - return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), nullptr, Name)); + const DataLayout &DL + = unwrap(B)->GetInsertBlock()->getModule()->getDataLayout(); + return wrap(unwrap(B)->CreateAlloca(DL, unwrap(Ty), nullptr, Name)); } LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Val, const char *Name) { - return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), unwrap(Val), Name)); + const DataLayout &DL + = unwrap(B)->GetInsertBlock()->getModule()->getDataLayout(); + + return wrap(unwrap(B)->CreateAlloca(DL, unwrap(Ty), unwrap(Val), Name)); } LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) { Index: lib/IR/DataLayout.cpp =================================================================== --- lib/IR/DataLayout.cpp +++ lib/IR/DataLayout.cpp @@ -180,6 +180,7 @@ LayoutMap = nullptr; BigEndian = false; + StackAddrSpace = 0; StackNaturalAlign = 0; ManglingMode = MM_None; NonIntegralAddressSpaces.clear(); @@ -358,6 +359,12 @@ StackNaturalAlign = inBytes(getInt(Tok)); break; } + case 'A': { // Default stack/alloca address space. + StackAddrSpace = getInt(Tok); + if (!isUInt<24>(StackAddrSpace)) + report_fatal_error("Invalid address space, must be a 24bit integer"); + break; + } case 'm': if (!Tok.empty()) report_fatal_error("Unexpected trailing characters after mangling specifier in datalayout string"); @@ -400,6 +407,7 @@ bool DataLayout::operator==(const DataLayout &Other) const { bool Ret = BigEndian == Other.BigEndian && + StackAddrSpace == Other.StackAddrSpace && StackNaturalAlign == Other.StackNaturalAlign && ManglingMode == Other.ManglingMode && LegalIntWidths == Other.LegalIntWidths && Index: lib/IR/Instructions.cpp =================================================================== --- lib/IR/Instructions.cpp +++ lib/IR/Instructions.cpp @@ -1199,34 +1199,38 @@ return Amt; } -AllocaInst::AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore) - : AllocaInst(Ty, /*ArraySize=*/nullptr, Name, InsertBefore) {} - -AllocaInst::AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd) - : AllocaInst(Ty, /*ArraySize=*/nullptr, Name, InsertAtEnd) {} - -AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, const Twine &Name, +AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, Instruction *InsertBefore) - : AllocaInst(Ty, ArraySize, /*Align=*/0, Name, InsertBefore) {} + : AllocaInst(Ty, AddrSpace, /*ArraySize=*/nullptr, Name, InsertBefore) {} -AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, const Twine &Name, +AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name, BasicBlock *InsertAtEnd) - : AllocaInst(Ty, ArraySize, /*Align=*/0, Name, InsertAtEnd) {} + : AllocaInst(Ty, AddrSpace, /*ArraySize=*/nullptr, Name, InsertAtEnd) {} -AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, unsigned Align, +AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, const Twine &Name, Instruction *InsertBefore) - : UnaryInstruction(PointerType::getUnqual(Ty), Alloca, - getAISize(Ty->getContext(), ArraySize), InsertBefore), - AllocatedType(Ty) { + : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/0, Name, InsertBefore) {} + +AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, + const Twine &Name, BasicBlock *InsertAtEnd) + : AllocaInst(Ty, AddrSpace, ArraySize, /*Align=*/0, Name, InsertAtEnd) {} + +AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, + unsigned Align, const Twine &Name, + Instruction *InsertBefore) + : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, + getAISize(Ty->getContext(), ArraySize), InsertBefore), + AllocatedType(Ty) { setAlignment(Align); assert(!Ty->isVoidTy() && "Cannot allocate void!"); setName(Name); } -AllocaInst::AllocaInst(Type *Ty, Value *ArraySize, unsigned Align, - const Twine &Name, BasicBlock *InsertAtEnd) - : UnaryInstruction(PointerType::getUnqual(Ty), Alloca, - getAISize(Ty->getContext(), ArraySize), InsertAtEnd), +AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, + unsigned Align, const Twine &Name, + BasicBlock *InsertAtEnd) + : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca, + getAISize(Ty->getContext(), ArraySize), InsertAtEnd), AllocatedType(Ty) { setAlignment(Align); assert(!Ty->isVoidTy() && "Cannot allocate void!"); @@ -3826,6 +3830,7 @@ AllocaInst *AllocaInst::cloneImpl() const { AllocaInst *Result = new AllocaInst(getAllocatedType(), + getType()->getAddressSpace(), (Value *)getOperand(0), getAlignment()); Result->setUsedWithInAlloca(isUsedWithInAlloca()); Result->setSwiftError(isSwiftError()); Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -3166,8 +3166,9 @@ void Verifier::visitAllocaInst(AllocaInst &AI) { SmallPtrSet Visited; PointerType *PTy = AI.getType(); - Assert(PTy->getAddressSpace() == 0, - "Allocation instruction pointer not in the generic address space!", + // TODO: Relax this restriction? + Assert(PTy->getAddressSpace() == DL.getStackAddrSpace(), + "Allocation instruction pointer not in the stack address space!", &AI); Assert(AI.getAllocatedType()->isSized(&Visited), "Cannot allocate unsized type", &AI); Index: lib/Target/NVPTX/NVPTXLowerArgs.cpp =================================================================== --- lib/Target/NVPTX/NVPTXLowerArgs.cpp +++ lib/Target/NVPTX/NVPTXLowerArgs.cpp @@ -159,7 +159,8 @@ assert(PType && "Expecting pointer type in handleByValParam"); Type *StructType = PType->getElementType(); - AllocaInst *AllocA = new AllocaInst(StructType, Arg->getName(), FirstInst); + unsigned AS = Func->getParent()->getDataLayout().getStackAddrSpace(); + AllocaInst *AllocA = new AllocaInst(StructType, AS, Arg->getName(), FirstInst); // Set the alignment to alignment of the byval parameter. This is because, // later load/stores assume that alignment, and we are going to replace // the use of the byval parameter with this alloca instruction. Index: lib/Target/X86/X86WinEHState.cpp =================================================================== --- lib/Target/X86/X86WinEHState.cpp +++ lib/Target/X86/X86WinEHState.cpp @@ -88,6 +88,7 @@ // Per-module data. Module *TheModule = nullptr; + const DataLayout *DL = nullptr; StructType *EHLinkRegistrationTy = nullptr; StructType *CXXEHRegistrationTy = nullptr; StructType *SEHRegistrationTy = nullptr; @@ -126,6 +127,7 @@ bool WinEHStatePass::doInitialization(Module &M) { TheModule = &M; + DL = &M.getDataLayout(); return false; } @@ -285,7 +287,7 @@ if (Personality == EHPersonality::MSVC_CXX) { RegNodeTy = getCXXEHRegistrationType(); - RegNode = Builder.CreateAlloca(RegNodeTy); + RegNode = Builder.CreateAlloca(*DL, RegNodeTy); // SavedESP = llvm.stacksave() Value *SP = Builder.CreateCall( Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {}); @@ -312,9 +314,9 @@ // Allocate local structures. RegNodeTy = getSEHRegistrationType(); - RegNode = Builder.CreateAlloca(RegNodeTy); + RegNode = Builder.CreateAlloca(*DL, RegNodeTy); if (UseStackGuard) - EHGuardNode = Builder.CreateAlloca(Int32Ty); + EHGuardNode = Builder.CreateAlloca(*DL, Int32Ty); // SavedESP = llvm.stacksave() Value *SP = Builder.CreateCall( Index: lib/Transforms/Coroutines/CoroElide.cpp =================================================================== --- lib/Transforms/Coroutines/CoroElide.cpp +++ lib/Transforms/Coroutines/CoroElide.cpp @@ -127,7 +127,8 @@ // is spilled into the coroutine frame and recreate the alignment information // here. Possibly we will need to do a mini SROA here and break the coroutine // frame into individual AllocaInst recreating the original alignment. - auto *Frame = new AllocaInst(FrameTy, "", InsertPt); + const DataLayout &DL = F->getParent()->getDataLayout(); + auto *Frame = new AllocaInst(FrameTy, DL.getStackAddrSpace(), "", InsertPt); auto *FrameVoidPtr = new BitCastInst(Frame, Type::getInt8PtrTy(C), "vFrame", InsertPt); Index: lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- lib/Transforms/Coroutines/CoroSplit.cpp +++ lib/Transforms/Coroutines/CoroSplit.cpp @@ -417,9 +417,11 @@ auto *AllocInst = CoroId->getCoroAlloc(); coro::replaceCoroFree(CoroId, /*Elide=*/AllocInst != nullptr); if (AllocInst) { + const DataLayout &DL = AllocInst->getModule()->getDataLayout(); + IRBuilder<> Builder(AllocInst); // FIXME: Need to handle overaligned members. - auto *Frame = Builder.CreateAlloca(FrameTy); + auto *Frame = Builder.CreateAlloca(DL, FrameTy); auto *VFrame = Builder.CreateBitCast(Frame, Builder.getInt8PtrTy()); AllocInst->replaceAllUsesWith(Builder.getFalse()); AllocInst->eraseFromParent(); Index: lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- lib/Transforms/IPO/ArgumentPromotion.cpp +++ lib/Transforms/IPO/ArgumentPromotion.cpp @@ -349,6 +349,8 @@ Call->eraseFromParent(); } + const DataLayout &DL = F->getParent()->getDataLayout(); + // Since we have now created the new function, splice the body of the old // function right into the new function, leaving the old rotting hulk of the // function empty. @@ -376,7 +378,8 @@ // Just add all the struct element types. Type *AgTy = cast(I->getType())->getElementType(); - Value *TheAlloca = new AllocaInst(AgTy, nullptr, "", InsertPt); + Value *TheAlloca = new AllocaInst(AgTy, DL.getStackAddrSpace(), nullptr, + "", InsertPt); StructType *STy = cast(AgTy); Value *Idxs[2] = {ConstantInt::get(Type::getInt32Ty(F->getContext()), 0), nullptr}; Index: lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- lib/Transforms/IPO/GlobalOpt.cpp +++ lib/Transforms/IPO/GlobalOpt.cpp @@ -1819,12 +1819,14 @@ GS.AccessingFunction->doesNotRecurse() && isPointerValueDeadOnEntryToFunction(GS.AccessingFunction, GV, LookupDomTree)) { + const DataLayout &DL = GV->getParent()->getDataLayout(); + DEBUG(dbgs() << "LOCALIZING GLOBAL: " << *GV << "\n"); Instruction &FirstI = const_cast(*GS.AccessingFunction ->getEntryBlock().begin()); Type *ElemTy = GV->getValueType(); // FIXME: Pass Global's alignment when globals have alignment - AllocaInst *Alloca = new AllocaInst(ElemTy, nullptr, + AllocaInst *Alloca = new AllocaInst(ElemTy, DL.getStackAddrSpace(), nullptr, GV->getName(), &FirstI); if (!isa(GV->getInitializer())) new StoreInst(GV->getInitializer(), Alloca, &FirstI); Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -138,7 +138,7 @@ Amt = AllocaBuilder.CreateAdd(Amt, Off); } - AllocaInst *New = AllocaBuilder.CreateAlloca(CastElTy, Amt); + AllocaInst *New = AllocaBuilder.CreateAlloca(DL, CastElTy, Amt); New->setAlignment(AI.getAlignment()); New->takeName(&AI); New->setUsedWithInAlloca(AI.isUsedWithInAlloca()); Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -185,7 +185,8 @@ // Convert: alloca Ty, C - where C is a constant != 1 into: alloca [C x Ty], 1 if (const ConstantInt *C = dyn_cast(AI.getArraySize())) { Type *NewTy = ArrayType::get(AI.getAllocatedType(), C->getZExtValue()); - AllocaInst *New = IC.Builder->CreateAlloca(NewTy, nullptr, AI.getName()); + AllocaInst *New = IC.Builder->CreateAlloca(IC.getDataLayout(), NewTy, + nullptr, AI.getName()); New->setAlignment(AI.getAlignment()); // Scan to the end of the allocation instructions, to skip over a block of Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -503,8 +503,7 @@ ArraySize = CI->getZExtValue(); } Type *Ty = AI.getAllocatedType(); - uint64_t SizeInBytes = - AI.getModule()->getDataLayout().getTypeAllocSize(Ty); + uint64_t SizeInBytes = DL->getTypeAllocSize(Ty); return SizeInBytes * ArraySize; } /// Check if we want (and can) handle this alloca. @@ -568,6 +567,7 @@ }; LLVMContext *C; + const DataLayout *DL; Triple TargetTriple; int LongSize; bool CompileKernel; @@ -639,6 +639,7 @@ bool Recover; Type *IntptrTy; LLVMContext *C; + const DataLayout *DL; Triple TargetTriple; ShadowMapping Mapping; Function *AsanPoisonGlobals; @@ -1930,6 +1931,7 @@ bool AddressSanitizerModule::runOnModule(Module &M) { C = &(M.getContext()); + DL = &M.getDataLayout(); int LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); TargetTriple = Triple(M.getTargetTriple()); @@ -2015,6 +2017,7 @@ GlobalsMD.init(M); C = &(M.getContext()); + DL = &M.getDataLayout(); LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); TargetTriple = Triple(M.getTargetTriple()); @@ -2388,12 +2391,14 @@ Value *FunctionStackPoisoner::createAllocaForLayout( IRBuilder<> &IRB, const ASanStackFrameLayout &L, bool Dynamic) { AllocaInst *Alloca; + + const DataLayout &DL = F.getParent()->getDataLayout(); if (Dynamic) { - Alloca = IRB.CreateAlloca(IRB.getInt8Ty(), + Alloca = IRB.CreateAlloca(DL, IRB.getInt8Ty(), ConstantInt::get(IRB.getInt64Ty(), L.FrameSize), "MyAlloca"); } else { - Alloca = IRB.CreateAlloca(ArrayType::get(IRB.getInt8Ty(), L.FrameSize), + Alloca = IRB.CreateAlloca(DL, ArrayType::get(IRB.getInt8Ty(), L.FrameSize), nullptr, "MyAlloca"); assert(Alloca->isStaticAlloca()); } @@ -2405,8 +2410,9 @@ void FunctionStackPoisoner::createDynamicAllocasInitStorage() { BasicBlock &FirstBB = *F.begin(); + const DataLayout &DL = F.getParent()->getDataLayout(); IRBuilder<> IRB(dyn_cast(FirstBB.begin())); - DynamicAllocaLayout = IRB.CreateAlloca(IntptrTy, nullptr); + DynamicAllocaLayout = IRB.CreateAlloca(DL, IntptrTy, nullptr); IRB.CreateStore(Constant::getNullValue(IntptrTy), DynamicAllocaLayout); DynamicAllocaLayout->setAlignment(32); } @@ -2777,7 +2783,9 @@ Value *NewSize = IRB.CreateAdd(OldSize, AdditionalChunkSize); // Insert new alloca with new NewSize and Align params. - AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), NewSize); + AllocaInst *NewAlloca = IRB.CreateAlloca(IRB.getInt8Ty(), + AI->getType()->getAddressSpace(), + NewSize); NewAlloca->setAlignment(Align); // NewAddress = Address + Align Index: lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -331,6 +331,10 @@ DFSanFunction &DFSF; DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {} + const DataLayout &getDataLayout() const { + return DFSF.F->getParent()->getDataLayout(); + } + void visitOperandShadowInst(Instruction &I); void visitBinaryOperator(BinaryOperator &BO); @@ -1312,7 +1316,8 @@ } if (AllLoadsStores) { IRBuilder<> IRB(&I); - DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(DFSF.DFS.ShadowTy); + DFSF.AllocaShadowMap[&I] = IRB.CreateAlloca(getDataLayout(), + DFSF.DFS.ShadowTy); } DFSF.setShadow(&I, DFSF.DFS.ZeroShadow); } @@ -1481,7 +1486,8 @@ auto *LabelVATy = ArrayType::get(DFSF.DFS.ShadowTy, CS.arg_size() - FT->getNumParams()); auto *LabelVAAlloca = new AllocaInst( - LabelVATy, "labelva", &DFSF.F->getEntryBlock().front()); + LabelVATy, getDataLayout().getStackAddrSpace(), + "labelva", &DFSF.F->getEntryBlock().front()); for (unsigned n = 0; i != CS.arg_end(); ++i, ++n) { auto LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, n); @@ -1494,8 +1500,9 @@ if (!FT->getReturnType()->isVoidTy()) { if (!DFSF.LabelReturnAlloca) { DFSF.LabelReturnAlloca = - new AllocaInst(DFSF.DFS.ShadowTy, "labelreturn", - &DFSF.F->getEntryBlock().front()); + new AllocaInst(DFSF.DFS.ShadowTy, + getDataLayout().getStackAddrSpace(), + "labelreturn", &DFSF.F->getEntryBlock().front()); } Args.push_back(DFSF.LabelReturnAlloca); } @@ -1574,7 +1581,8 @@ unsigned VarArgSize = CS.arg_size() - FT->getNumParams(); ArrayType *VarArgArrayTy = ArrayType::get(DFSF.DFS.ShadowTy, VarArgSize); AllocaInst *VarArgShadow = - new AllocaInst(VarArgArrayTy, "", &DFSF.F->getEntryBlock().front()); + new AllocaInst(VarArgArrayTy, getDataLayout().getStackAddrSpace(), + "", &DFSF.F->getEntryBlock().front()); Args.push_back(IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, 0)); for (unsigned n = 0; i != e; ++i, ++n) { IRB.CreateStore( Index: lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -3062,6 +3062,8 @@ } void finalizeInstrumentation() override { + const DataLayout &DL = F.getParent()->getDataLayout(); + assert(!VAArgOverflowSize && !VAArgTLSCopy && "finalizeInstrumentation called twice"); if (!VAStartInstrumentationList.empty()) { @@ -3072,7 +3074,7 @@ Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize); - VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); + VAArgTLSCopy = IRB.CreateAlloca(DL, Type::getInt8Ty(*MS.C), CopySize); IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); } @@ -3189,9 +3191,11 @@ VAArgSize); if (!VAStartInstrumentationList.empty()) { + const DataLayout &DL = F.getParent()->getDataLayout(); + // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. - VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); + VAArgTLSCopy = IRB.CreateAlloca(DL, Type::getInt8Ty(*MS.C), CopySize); IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); } @@ -3362,6 +3366,7 @@ assert(!VAArgOverflowSize && !VAArgTLSCopy && "finalizeInstrumentation called twice"); if (!VAStartInstrumentationList.empty()) { + const DataLayout &DL = F.getParent()->getDataLayout(); // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); @@ -3369,7 +3374,7 @@ Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize); - VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); + VAArgTLSCopy = IRB.CreateAlloca(DL, Type::getInt8Ty(*MS.C), CopySize); IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); } @@ -3592,9 +3597,11 @@ VAArgSize); if (!VAStartInstrumentationList.empty()) { + const DataLayout &DL = F.getParent()->getDataLayout(); + // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. - VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); + VAArgTLSCopy = IRB.CreateAlloca(DL, Type::getInt8Ty(*MS.C), CopySize); IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); } Index: lib/Transforms/Scalar/RewriteStatepointsForGC.cpp =================================================================== --- lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1615,8 +1615,10 @@ // Emit alloca for "LiveValue" and record it in "allocaMap" and // "PromotableAllocas" + const DataLayout &DL = F.getParent()->getDataLayout(); auto emitAllocaFor = [&](Value *LiveValue) { - AllocaInst *Alloca = new AllocaInst(LiveValue->getType(), "", + AllocaInst *Alloca = new AllocaInst(LiveValue->getType(), + DL.getStackAddrSpace(), "", F.getEntryBlock().getFirstNonPHI()); AllocaMap[LiveValue] = Alloca; PromotableAllocas.push_back(Alloca); Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -2295,7 +2295,8 @@ #endif return getAdjustedPtr(IRB, DL, &NewAI, - APInt(DL.getPointerSizeInBits(), Offset), PointerTy, + APInt(DL.getPointerTypeSizeInBits(PointerTy), Offset), + PointerTy, #ifndef NDEBUG Twine(OldName) + "." #else @@ -2370,6 +2371,8 @@ Value *OldOp = LI.getOperand(0); assert(OldOp == OldPtr); + unsigned AS = LI.getPointerAddressSpace(); + Type *TargetTy = IsSplit ? Type::getIntNTy(LI.getContext(), SliceSize * 8) : LI.getType(); const bool IsLoadPastEnd = DL.getTypeStoreSize(TargetTy) > SliceSize; @@ -2402,7 +2405,7 @@ "endian_shift"); } } else { - Type *LTy = TargetTy->getPointerTo(); + Type *LTy = TargetTy->getPointerTo(AS); LoadInst *NewLI = IRB.CreateAlignedLoad(getNewAllocaSlicePtr(IRB, LTy), getSliceAlign(TargetTy), LI.isVolatile(), LI.getName()); @@ -2430,7 +2433,7 @@ // the computed value, and then replace the placeholder with LI, leaving // LI only used for this computation. Value *Placeholder = - new LoadInst(UndefValue::get(LI.getType()->getPointerTo())); + new LoadInst(UndefValue::get(LI.getType()->getPointerTo(AS))); V = insertInteger(DL, IRB, Placeholder, V, NewBeginOffset - BeginOffset, "insert"); LI.replaceAllUsesWith(V); @@ -2543,7 +2546,8 @@ NewSI = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment(), SI.isVolatile()); } else { - Value *NewPtr = getNewAllocaSlicePtr(IRB, V->getType()->getPointerTo()); + unsigned AS = SI.getPointerAddressSpace(); + Value *NewPtr = getNewAllocaSlicePtr(IRB, V->getType()->getPointerTo(AS)); NewSI = IRB.CreateAlignedStore(V, NewPtr, getSliceAlign(V->getType()), SI.isVolatile()); } @@ -3858,7 +3862,7 @@ if (Alignment <= DL.getABITypeAlignment(SliceTy)) Alignment = 0; NewAI = new AllocaInst( - SliceTy, nullptr, Alignment, + SliceTy, AI.getType()->getAddressSpace(), nullptr, Alignment, AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()), &AI); ++NumNewAllocas; } Index: lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- lib/Transforms/Utils/CodeExtractor.cpp +++ lib/Transforms/Utils/CodeExtractor.cpp @@ -440,8 +440,10 @@ // Emit a call to the new function, passing in: *pointer to struct (if // aggregating parameters), or plan inputs and allocated memory for outputs std::vector params, StructValues, ReloadOutputs, Reloads; - - LLVMContext &Context = newFunction->getContext(); + + Module *M = newFunction->getParent(); + LLVMContext &Context = M->getContext(); + const DataLayout &DL = M->getDataLayout(); // Add inputs as params, or to be filled into the struct for (Value *input : inputs) @@ -456,8 +458,9 @@ StructValues.push_back(output); } else { AllocaInst *alloca = - new AllocaInst(output->getType(), nullptr, output->getName() + ".loc", - &codeReplacer->getParent()->front().front()); + new AllocaInst(output->getType(), DL.getStackAddrSpace(), + nullptr, output->getName() + ".loc", + &codeReplacer->getParent()->front().front()); ReloadOutputs.push_back(alloca); params.push_back(alloca); } @@ -473,7 +476,8 @@ // Allocate a struct at the beginning of this function StructArgTy = StructType::get(newFunction->getContext(), ArgTypes); - Struct = new AllocaInst(StructArgTy, nullptr, "structArg", + Struct = new AllocaInst(StructArgTy, DL.getStackAddrSpace(), nullptr, + "structArg", &codeReplacer->getParent()->front().front()); params.push_back(Struct); Index: lib/Transforms/Utils/DemoteRegToStack.cpp =================================================================== --- lib/Transforms/Utils/DemoteRegToStack.cpp +++ lib/Transforms/Utils/DemoteRegToStack.cpp @@ -28,15 +28,17 @@ return nullptr; } + Function *F = I.getParent()->getParent(); + const DataLayout &DL = F->getParent()->getDataLayout(); + // Create a stack slot to hold the value. AllocaInst *Slot; if (AllocaPoint) { - Slot = new AllocaInst(I.getType(), nullptr, + Slot = new AllocaInst(I.getType(), DL.getStackAddrSpace(), nullptr, I.getName()+".reg2mem", AllocaPoint); } else { - Function *F = I.getParent()->getParent(); - Slot = new AllocaInst(I.getType(), nullptr, I.getName() + ".reg2mem", - &F->getEntryBlock().front()); + Slot = new AllocaInst(I.getType(), DL.getStackAddrSpace(), nullptr, + I.getName() + ".reg2mem", &F->getEntryBlock().front()); } // We cannot demote invoke instructions to the stack if their normal edge @@ -110,14 +112,17 @@ return nullptr; } + const DataLayout &DL = P->getModule()->getDataLayout(); + // Create a stack slot to hold the value. AllocaInst *Slot; if (AllocaPoint) { - Slot = new AllocaInst(P->getType(), nullptr, + Slot = new AllocaInst(P->getType(), DL.getStackAddrSpace(), nullptr, P->getName()+".reg2mem", AllocaPoint); } else { Function *F = P->getParent()->getParent(); - Slot = new AllocaInst(P->getType(), nullptr, P->getName() + ".reg2mem", + Slot = new AllocaInst(P->getType(), DL.getStackAddrSpace(), nullptr, + P->getName() + ".reg2mem", &F->getEntryBlock().front()); } Index: lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- lib/Transforms/Utils/InlineFunction.cpp +++ lib/Transforms/Utils/InlineFunction.cpp @@ -1224,6 +1224,7 @@ Type *AggTy = ArgTy->getElementType(); Function *Caller = TheCall->getFunction(); + const DataLayout &DL = Caller->getParent()->getDataLayout(); // If the called function is readonly, then it could not mutate the caller's // copy of the byval'd memory. In this case, it is safe to elide the copy and @@ -1237,31 +1238,30 @@ AssumptionCache *AC = IFI.GetAssumptionCache ? &(*IFI.GetAssumptionCache)(*Caller) : nullptr; - const DataLayout &DL = Caller->getParent()->getDataLayout(); // If the pointer is already known to be sufficiently aligned, or if we can // round it up to a larger alignment, then we don't need a temporary. if (getOrEnforceKnownAlignment(Arg, ByValAlignment, DL, TheCall, AC) >= ByValAlignment) return Arg; - + // Otherwise, we have to make a memcpy to get a safe alignment. This is bad // for code quality, but rarely happens and is required for correctness. } // Create the alloca. If we have DataLayout, use nice alignment. - unsigned Align = - Caller->getParent()->getDataLayout().getPrefTypeAlignment(AggTy); + unsigned Align = DL.getPrefTypeAlignment(AggTy); // If the byval had an alignment specified, we *must* use at least that // alignment, as it is required by the byval argument (and uses of the // pointer inside the callee). Align = std::max(Align, ByValAlignment); - - Value *NewAlloca = new AllocaInst(AggTy, nullptr, Align, Arg->getName(), + + Value *NewAlloca = new AllocaInst(AggTy, DL.getStackAddrSpace(), + nullptr, Align, Arg->getName(), &*Caller->begin()->begin()); IFI.StaticAllocas.push_back(cast(NewAlloca)); - + // Uses of the argument in the function should use our new alloca // instead. return NewAlloca; Index: test/Assembler/alloca-addrspace-parse-error-0.ll =================================================================== --- /dev/null +++ test/Assembler/alloca-addrspace-parse-error-0.ll @@ -0,0 +1,11 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +target datalayout = "A1" + +; CHECK: :8:3: error: expected metadata after comma +define void @use_alloca() { + %alloca = alloca i32, addrspace(1), + ret void +} + +!0 = !{} Index: test/Assembler/alloca-addrspace-parse-error-1.ll =================================================================== --- /dev/null +++ test/Assembler/alloca-addrspace-parse-error-1.ll @@ -0,0 +1,12 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +target datalayout = "A1" + +; addrspace and align in wrong order +; CHECK: :8:39: error: expected metadata after comma +define void @use_alloca() { + %alloca = alloca i32, addrspace(1), align 4 + ret void +} + +!0 = !{} Index: test/Assembler/alloca-addrspace0.ll =================================================================== --- /dev/null +++ test/Assembler/alloca-addrspace0.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +target datalayout = "A0" +; CHECK: target datalayout = "A0" + + +; CHECK: %alloca_scalar_no_align = alloca i32 +; CHECK-NEXT: %alloca_scalar_align4 = alloca i32, align 4 +; CHECK-NEXT: %alloca_scalar_no_align_metadata = alloca i32, !foo !0 +; CHECK-NEXT: %alloca_scalar_align4_metadata = alloca i32, align 4, !foo !0 +; CHECK-NEXT: %alloca_inalloca_scalar_no_align = alloca inalloca i32 +; CHECK-NEXT: %alloca_inalloca_scalar_align4_metadata = alloca inalloca i32, align 4, !foo !0 +define void @use_alloca() { + %alloca_scalar_no_align = alloca i32, addrspace(0) + %alloca_scalar_align4 = alloca i32, align 4, addrspace(0) + %alloca_scalar_no_align_metadata = alloca i32, addrspace(0), !foo !0 + %alloca_scalar_align4_metadata = alloca i32, align 4, addrspace(0), !foo !0 + %alloca_inalloca_scalar_no_align = alloca inalloca i32, addrspace(0) + %alloca_inalloca_scalar_align4_metadata = alloca inalloca i32, align 4, addrspace(0), !foo !0 + + ret void +} + +!0 = !{} Index: test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll =================================================================== --- /dev/null +++ test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll @@ -0,0 +1,9 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +target datalayout = "A1" + +; CHECK: :7:41: error: address space must match datalayout +define void @use_alloca() { + %alloca_scalar_no_align = alloca i32, addrspace(2) + ret void +} Index: test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll =================================================================== --- /dev/null +++ test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll @@ -0,0 +1,9 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +target datalayout = "A1" + +; CHECK: :7:50: error: address space must match datalayout +define void @use_alloca() { + %alloca_scalar_no_align = alloca i32, align 4, addrspace(2) + ret void +} Index: test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll =================================================================== --- /dev/null +++ test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll @@ -0,0 +1,11 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +target datalayout = "A1" + +; CHECK: :7:50: error: address space must match datalayout +define void @use_alloca() { + %alloca_scalar_no_align = alloca i32, align 4, addrspace(2), !foo !0 + ret void +} + +!0 = !{} Index: test/Assembler/datalayout-alloca-addrspace.ll =================================================================== --- /dev/null +++ test/Assembler/datalayout-alloca-addrspace.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +target datalayout = "A1" +; CHECK: target datalayout = "A1" + +; CHECK: %alloca_scalar_no_align = alloca i32, addrspace(1) +; CHECK-NEXT: %alloca_scalar_align4 = alloca i32, align 4, addrspace(1) +; CHECK-NEXT: %alloca_scalar_no_align_metadata = alloca i32, addrspace(1), !foo !0 +; CHECK-NEXT: %alloca_scalar_align4_metadata = alloca i32, align 4, addrspace(1), !foo !0 +; CHECK-NEXT: %alloca_inalloca_scalar_no_align = alloca inalloca i32, addrspace(1) +; CHECK-NEXT: %alloca_inalloca_scalar_align4_metadata = alloca inalloca i32, align 4, addrspace(1), !foo !0 +define void @use_alloca() { + %alloca_scalar_no_align = alloca i32, addrspace(1) + %alloca_scalar_align4 = alloca i32, align 4, addrspace(1) + %alloca_scalar_no_align_metadata = alloca i32, addrspace(1), !foo !0 + %alloca_scalar_align4_metadata = alloca i32, align 4, addrspace(1), !foo !0 + %alloca_inalloca_scalar_no_align = alloca inalloca i32, addrspace(1) + %alloca_inalloca_scalar_align4_metadata = alloca inalloca i32, align 4, addrspace(1), !foo !0 + + ret void +} + +!0 = !{} Index: test/Assembler/invalid-datalayout-alloca-addrspace.ll =================================================================== --- /dev/null +++ test/Assembler/invalid-datalayout-alloca-addrspace.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as < %s 2>&1 | FileCheck %s + +target datalayout = "A16777216" +; CHECK: Invalid address space, must be a 24bit integer Index: test/Transforms/SROA/alloca-address-space.ll =================================================================== --- /dev/null +++ test/Transforms/SROA/alloca-address-space.ll @@ -0,0 +1,84 @@ +; RUN: opt < %s -sroa -S | FileCheck %s +target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64-A2" + +declare void @llvm.memcpy.p2i8.p2i8.i32(i8 addrspace(2)* nocapture, i8 addrspace(2)* nocapture readonly, i32, i32, i1) +declare void @llvm.memcpy.p1i8.p2i8.i32(i8 addrspace(1)* nocapture, i8 addrspace(2)* nocapture readonly, i32, i32, i1) +declare void @llvm.memcpy.p2i8.p1i8.i32(i8 addrspace(2)* nocapture, i8 addrspace(1)* nocapture readonly, i32, i32, i1) +declare void @llvm.memcpy.p1i8.p1i8.i32(i8 addrspace(1)* nocapture, i8 addrspace(1)* nocapture readonly, i32, i32, i1) + + + +; CHECK-LABEL: @test_address_space_1_1( +; CHECK: load <2 x i64>, <2 x i64> addrspace(1)* %a, align 2 +; CHECK: store <2 x i64> {{.*}}, <2 x i64> addrspace(1)* {{.*}}, align 2 +; CHECK: ret void +define void @test_address_space_1_1(<2 x i64> addrspace(1)* %a, i16 addrspace(1)* %b) { + %aa = alloca <2 x i64>, align 16, addrspace(2) + %aptr = bitcast <2 x i64> addrspace(1)* %a to i8 addrspace(1)* + %aaptr = bitcast <2 x i64> addrspace(2)* %aa to i8 addrspace(2)* + call void @llvm.memcpy.p2i8.p1i8.i32(i8 addrspace(2)* %aaptr, i8 addrspace(1)* %aptr, i32 16, i32 2, i1 false) + %bptr = bitcast i16 addrspace(1)* %b to i8 addrspace(1)* + call void @llvm.memcpy.p1i8.p2i8.i32(i8 addrspace(1)* %bptr, i8 addrspace(2)* %aaptr, i32 16, i32 2, i1 false) + ret void +} + +; CHECK-LABEL: @test_address_space_1_0( +; CHECK: load <2 x i64>, <2 x i64> addrspace(1)* %a, align 2 +; CHECK: store <2 x i64> {{.*}}, <2 x i64> addrspace(2)* {{.*}}, align 2 +; CHECK: ret void +define void @test_address_space_1_0(<2 x i64> addrspace(1)* %a, i16 addrspace(2)* %b) { + %aa = alloca <2 x i64>, align 16, addrspace(2) + %aptr = bitcast <2 x i64> addrspace(1)* %a to i8 addrspace(1)* + %aaptr = bitcast <2 x i64> addrspace(2)* %aa to i8 addrspace(2)* + call void @llvm.memcpy.p2i8.p1i8.i32(i8 addrspace(2)* %aaptr, i8 addrspace(1)* %aptr, i32 16, i32 2, i1 false) + %bptr = bitcast i16 addrspace(2)* %b to i8 addrspace(2)* + call void @llvm.memcpy.p2i8.p2i8.i32(i8 addrspace(2)* %bptr, i8 addrspace(2)* %aaptr, i32 16, i32 2, i1 false) + ret void +} + +; CHECK-LABEL: @test_address_space_0_1( +; CHECK: load <2 x i64>, <2 x i64> addrspace(2)* %a, align 2 +; CHECK: store <2 x i64> {{.*}}, <2 x i64> addrspace(1)* {{.*}}, align 2 +; CHECK: ret void +define void @test_address_space_0_1(<2 x i64> addrspace(2)* %a, i16 addrspace(1)* %b) { + %aa = alloca <2 x i64>, align 16, addrspace(2) + %aptr = bitcast <2 x i64> addrspace(2)* %a to i8 addrspace(2)* + %aaptr = bitcast <2 x i64> addrspace(2)* %aa to i8 addrspace(2)* + call void @llvm.memcpy.p2i8.p2i8.i32(i8 addrspace(2)* %aaptr, i8 addrspace(2)* %aptr, i32 16, i32 2, i1 false) + %bptr = bitcast i16 addrspace(1)* %b to i8 addrspace(1)* + call void @llvm.memcpy.p1i8.p2i8.i32(i8 addrspace(1)* %bptr, i8 addrspace(2)* %aaptr, i32 16, i32 2, i1 false) + ret void +} + +%struct.struct_test_27.0.13 = type { i32, float, i64, i8, [4 x i32] } + +; CHECK-LABEL: @copy_struct( +; CHECK-NOT: memcpy +define void @copy_struct([5 x i64] %in.coerce) { +for.end: + %in = alloca %struct.struct_test_27.0.13, align 8, addrspace(2) + %0 = bitcast %struct.struct_test_27.0.13 addrspace(2)* %in to [5 x i64] addrspace(2)* + store [5 x i64] %in.coerce, [5 x i64] addrspace(2)* %0, align 8 + %scevgep9 = getelementptr %struct.struct_test_27.0.13, %struct.struct_test_27.0.13 addrspace(2)* %in, i32 0, i32 4, i32 0 + %scevgep910 = bitcast i32 addrspace(2)* %scevgep9 to i8 addrspace(2)* + call void @llvm.memcpy.p1i8.p2i8.i32(i8 addrspace(1)* undef, i8 addrspace(2)* %scevgep910, i32 16, i32 4, i1 false) + ret void +} + +%union.anon = type { i32* } + +@g = common global i32 0, align 4 +@l = common addrspace(3) global i32 0, align 4 + +; Make sure an illegal bitcast isn't introduced +; CHECK-LABEL: @pr27557( +; CHECK: %[[CAST:.*]] = bitcast i32* addrspace(2)* {{.*}} to i32 addrspace(3)* addrspace(2)* +; CHECK: store i32 addrspace(3)* @l, i32 addrspace(3)* addrspace(2)* %[[CAST]] +define void @pr27557() { + %1 = alloca %union.anon, align 8, addrspace(2) + %2 = bitcast %union.anon addrspace(2)* %1 to i32* addrspace(2)* + store i32* @g, i32* addrspace(2)* %2, align 8 + %3 = bitcast %union.anon addrspace(2)* %1 to i32 addrspace(3)* addrspace(2)* + store i32 addrspace(3)* @l, i32 addrspace(3)* addrspace(2)* %3, align 8 + ret void +} Index: tools/llvm-stress/llvm-stress.cpp =================================================================== --- tools/llvm-stress/llvm-stress.cpp +++ tools/llvm-stress/llvm-stress.cpp @@ -424,7 +424,9 @@ void Act() override { Type *Tp = pickType(); - PT->push_back(new AllocaInst(Tp, "A", BB->getFirstNonPHI())); + const DataLayout &DL = BB->getModule()->getDataLayout(); + PT->push_back(new AllocaInst(Tp, DL.getStackAddrSpace(), + "A", BB->getFirstNonPHI())); } }; Index: unittests/Analysis/ScalarEvolutionTest.cpp =================================================================== --- unittests/Analysis/ScalarEvolutionTest.cpp +++ unittests/Analysis/ScalarEvolutionTest.cpp @@ -306,9 +306,11 @@ // %bitcast2 = bitcast i8* %select to i32* // br i1 undef, label %loop, label %exit + const DataLayout &DL = F->getParent()->getDataLayout(); BranchInst *Br = BranchInst::Create( LoopBB, ExitBB, UndefValue::get(Type::getInt1Ty(Context)), LoopBB); - AllocaInst *Alloca = new AllocaInst(I32Ty, "alloca", Br); + AllocaInst *Alloca = new AllocaInst(I32Ty, DL.getStackAddrSpace(), + "alloca", Br); ConstantInt *Ci32 = ConstantInt::get(Context, APInt(32, 1)); GetElementPtrInst *Gep0 = GetElementPtrInst::Create(I32Ty, Alloca, Ci32, "gep0", Br); Index: unittests/IR/IRBuilderTest.cpp =================================================================== --- unittests/IR/IRBuilderTest.cpp +++ unittests/IR/IRBuilderTest.cpp @@ -34,6 +34,7 @@ BB = BasicBlock::Create(Ctx, "", F); GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true, GlobalValue::ExternalLinkage, nullptr); + DL = &M->getDataLayout(); } void TearDown() override { @@ -46,13 +47,14 @@ Function *F; BasicBlock *BB; GlobalVariable *GV; + const DataLayout *DL; }; TEST_F(IRBuilderTest, Lifetime) { IRBuilder<> Builder(BB); - AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty()); - AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty()); - AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(), + AllocaInst *Var1 = Builder.CreateAlloca(*DL, Builder.getInt8Ty()); + AllocaInst *Var2 = Builder.CreateAlloca(*DL, Builder.getInt32Ty()); + AllocaInst *Var3 = Builder.CreateAlloca(*DL, Builder.getInt8Ty(), Builder.getInt32(123)); CallInst *Start1 = Builder.CreateLifetimeStart(Var1); @@ -347,7 +349,7 @@ auto SP = DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, DINode::FlagZero, true); F->setSubprogram(SP); - AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty()); + AllocaInst *I = Builder.CreateAlloca(*DL, Builder.getInt8Ty()); auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1, DINode::FlagZero, true); auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0); Index: unittests/Transforms/Utils/Cloning.cpp =================================================================== --- unittests/Transforms/Utils/Cloning.cpp +++ unittests/Transforms/Utils/Cloning.cpp @@ -293,7 +293,8 @@ IBuilder.SetInsertPoint(Entry); DebugLoc Loc = DebugLoc::get(3, 2, Subprogram); IBuilder.SetCurrentDebugLocation(Loc); - AllocaInst* Alloca = IBuilder.CreateAlloca(IntegerType::getInt32Ty(C)); + AllocaInst* Alloca = IBuilder.CreateAlloca(M->getDataLayout(), + IntegerType::getInt32Ty(C)); IBuilder.SetCurrentDebugLocation(DebugLoc::get(4, 2, Subprogram)); Value* AllocaContent = IBuilder.getInt32(1); Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca); Index: unittests/Transforms/Utils/MemorySSA.cpp =================================================================== --- unittests/Transforms/Utils/MemorySSA.cpp +++ unittests/Transforms/Utils/MemorySSA.cpp @@ -553,7 +553,7 @@ GlobalValue::ExternalLinkage, "F", &M); B.SetInsertPoint(BasicBlock::Create(C, "", F)); Type *Int8 = Type::getInt8Ty(C); - Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A"); + Value *Alloca = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "A"); StoreInst *S1 = B.CreateStore(ConstantInt::get(Int8, 0), Alloca); StoreInst *S2 = B.CreateStore(ConstantInt::get(Int8, 1), Alloca); StoreInst *S3 = B.CreateStore(ConstantInt::get(Int8, 2), Alloca); @@ -584,7 +584,7 @@ GlobalValue::ExternalLinkage, "F", &M); B.SetInsertPoint(BasicBlock::Create(C, "", F)); Type *Int8 = Type::getInt8Ty(C); - Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A"); + Value *Alloca = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "A"); Instruction *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca); Instruction *LI = B.CreateLoad(Alloca); @@ -614,7 +614,7 @@ GlobalValue::ExternalLinkage, "F", &M); B.SetInsertPoint(BasicBlock::Create(C, "", F)); Type *Int8 = Type::getInt8Ty(C); - Value *Alloca = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A"); + Value *Alloca = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "A"); StoreInst *SI = B.CreateStore(ConstantInt::get(Int8, 0), Alloca); setupAnalyses(); @@ -660,8 +660,8 @@ Type *Int8 = Type::getInt8Ty(C); Constant *One = ConstantInt::get(Int8, 1); Constant *Zero = ConstantInt::get(Int8, 0); - Value *AllocA = B.CreateAlloca(Int8, One, "a"); - Value *AllocB = B.CreateAlloca(Int8, One, "b"); + Value *AllocA = B.CreateAlloca(DL, Int8, One, "a"); + Value *AllocB = B.CreateAlloca(DL, Int8, One, "b"); BasicBlock *IfThen = BasicBlock::Create(C, "B", F); BasicBlock *IfEnd = BasicBlock::Create(C, "C", F); @@ -723,7 +723,7 @@ B.SetInsertPoint(BasicBlock::Create(C, "", F)); Type *Int8 = Type::getInt8Ty(C); Constant *One = ConstantInt::get(Int8, 1); - Value *AllocA = B.CreateAlloca(Int8, One, ""); + Value *AllocA = B.CreateAlloca(DL, Int8, One, ""); Instruction *Store = B.CreateStore(One, AllocA); Instruction *Load = B.CreateLoad(AllocA); @@ -751,9 +751,9 @@ GlobalValue::ExternalLinkage, "F", &M); B.SetInsertPoint(BasicBlock::Create(C, "", F)); Type *Int8 = Type::getInt8Ty(C); - Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A"); + Value *AllocaA = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "A"); Instruction *SIA = B.CreateStore(ConstantInt::get(Int8, 0), AllocaA); - Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B"); + Value *AllocaB = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "B"); Instruction *SIB = B.CreateStore(ConstantInt::get(Int8, 0), AllocaB); Instruction *LIA = B.CreateLoad(AllocaA); @@ -783,9 +783,9 @@ B.SetInsertPoint(BasicBlock::Create(C, "", F)); Type *Int8 = Type::getInt8Ty(C); - Value *A = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A"); - Value *B_ = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B"); - Value *C = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "C"); + Value *A = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "A"); + Value *B_ = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "B"); + Value *C = B.CreateAlloca(DL, Int8, ConstantInt::get(Int8, 1), "C"); StoreInst *StoreA0 = B.CreateStore(ConstantInt::get(Int8, 0), A); StoreInst *StoreB = B.CreateStore(ConstantInt::get(Int8, 0), B_);