Index: llvm/trunk/include/llvm/AsmParser/Parser.h =================================================================== --- llvm/trunk/include/llvm/AsmParser/Parser.h +++ llvm/trunk/include/llvm/AsmParser/Parser.h @@ -39,9 +39,11 @@ /// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. /// This option should only be set to false by llvm-as /// for use inside the LLVM testuite! +/// \param DataLayoutString Override datalayout in the llvm assembly. std::unique_ptr parseAssemblyFile(StringRef Filename, SMDiagnostic &Error, LLVMContext &Context, - SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true); + SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true, + StringRef DataLayoutString = ""); /// The function is a secondary interface to the LLVM Assembly Parser. It parses /// an ASCII string that (presumably) contains LLVM Assembly code. It returns a @@ -57,11 +59,13 @@ /// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. /// This option should only be set to false by llvm-as /// for use inside the LLVM testuite! +/// \param DataLayoutString Override datalayout in the llvm assembly. std::unique_ptr parseAssemblyString(StringRef AsmString, SMDiagnostic &Error, LLVMContext &Context, SlotMapping *Slots = nullptr, - bool UpgradeDebugInfo = true); + bool UpgradeDebugInfo = true, + StringRef DataLayoutString = ""); /// parseAssemblyFile and parseAssemblyString are wrappers around this function. /// \brief Parse LLVM Assembly from a MemoryBuffer. @@ -72,10 +76,12 @@ /// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. /// This option should only be set to false by llvm-as /// for use inside the LLVM testuite! +/// \param DataLayoutString Override datalayout in the llvm assembly. std::unique_ptr parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, SlotMapping *Slots = nullptr, - bool UpgradeDebugInfo = true); + bool UpgradeDebugInfo = true, + StringRef DataLayoutString = ""); /// This function is the low-level interface to the LLVM Assembly Parser. /// This is kept as an independent function instead of being inlined into @@ -91,9 +97,11 @@ /// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. /// This option should only be set to false by llvm-as /// for use inside the LLVM testuite! +/// \param DataLayoutString Override datalayout in the llvm assembly. bool parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err, SlotMapping *Slots = nullptr, - bool UpgradeDebugInfo = true); + bool UpgradeDebugInfo = true, + StringRef DataLayoutString = ""); /// Parse a type and a constant value in the given string. /// Index: llvm/trunk/include/llvm/IRReader/IRReader.h =================================================================== --- llvm/trunk/include/llvm/IRReader/IRReader.h +++ llvm/trunk/include/llvm/IRReader/IRReader.h @@ -15,6 +15,7 @@ #ifndef LLVM_IRREADER_IRREADER_H #define LLVM_IRREADER_IRREADER_H +#include "llvm/ADT/StringRef.h" #include namespace llvm { @@ -40,9 +41,11 @@ /// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. /// This option should only be set to false by llvm-as /// for use inside the LLVM testuite! +/// \param DataLayoutString Override datalayout in the llvm assembly. std::unique_ptr parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err, LLVMContext &Context, - bool UpgradeDebugInfo = true); + bool UpgradeDebugInfo = true, + StringRef DataLayoutString = ""); /// If the given file holds a bitcode image, return a Module for it. /// Otherwise, attempt to parse it as LLVM Assembly and return a Module @@ -50,9 +53,11 @@ /// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier. /// This option should only be set to false by llvm-as /// for use inside the LLVM testuite! +/// \param DataLayoutString Override datalayout in the llvm assembly. std::unique_ptr parseIRFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, - bool UpgradeDebugInfo = true); + bool UpgradeDebugInfo = true, + StringRef DataLayoutString = ""); } #endif Index: llvm/trunk/lib/AsmParser/LLParser.h =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.h +++ llvm/trunk/lib/AsmParser/LLParser.h @@ -143,12 +143,19 @@ /// UpgradeDebuginfo so it can generate broken bitcode. bool UpgradeDebugInfo; + /// DataLayout string to override that in LLVM assembly. + StringRef DataLayoutStr; + public: LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M, - SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true) + SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true, + StringRef DataLayoutString = "") : Context(M->getContext()), Lex(F, SM, Err, M->getContext()), M(M), Slots(Slots), BlockAddressPFS(nullptr), - UpgradeDebugInfo(UpgradeDebugInfo) {} + UpgradeDebugInfo(UpgradeDebugInfo), DataLayoutStr(DataLayoutString) { + if (!DataLayoutStr.empty()) + M->setDataLayout(DataLayoutStr); + } bool Run(); bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots); Index: llvm/trunk/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp +++ llvm/trunk/lib/AsmParser/LLParser.cpp @@ -327,7 +327,8 @@ if (ParseToken(lltok::equal, "expected '=' after target datalayout") || ParseStringConstant(Str)) return true; - M->setDataLayout(Str); + if (DataLayoutStr.empty()) + M->setDataLayout(Str); return false; } } @@ -6261,14 +6262,7 @@ if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - const DataLayout &DL = M->getDataLayout(); - unsigned AS = DL.getAllocaAddrSpace(); - 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); + AllocaInst *AI = new AllocaInst(Ty, AddrSpace, Size, Alignment); AI->setUsedWithInAlloca(IsInAlloca); AI->setSwiftError(IsSwiftError); Inst = AI; Index: llvm/trunk/lib/AsmParser/Parser.cpp =================================================================== --- llvm/trunk/lib/AsmParser/Parser.cpp +++ llvm/trunk/lib/AsmParser/Parser.cpp @@ -23,31 +23,34 @@ using namespace llvm; bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err, - SlotMapping *Slots, bool UpgradeDebugInfo) { + SlotMapping *Slots, bool UpgradeDebugInfo, + StringRef DataLayoutString) { SourceMgr SM; std::unique_ptr Buf = MemoryBuffer::getMemBuffer(F); SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); - return LLParser(F.getBuffer(), SM, Err, &M, Slots, UpgradeDebugInfo).Run(); + return LLParser(F.getBuffer(), SM, Err, &M, Slots, UpgradeDebugInfo, + DataLayoutString) + .Run(); } std::unique_ptr llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, - SlotMapping *Slots, bool UpgradeDebugInfo) { + SlotMapping *Slots, bool UpgradeDebugInfo, + StringRef DataLayoutString) { std::unique_ptr M = make_unique(F.getBufferIdentifier(), Context); - if (parseAssemblyInto(F, *M, Err, Slots, UpgradeDebugInfo)) + if (parseAssemblyInto(F, *M, Err, Slots, UpgradeDebugInfo, DataLayoutString)) return nullptr; return M; } -std::unique_ptr llvm::parseAssemblyFile(StringRef Filename, - SMDiagnostic &Err, - LLVMContext &Context, - SlotMapping *Slots, - bool UpgradeDebugInfo) { +std::unique_ptr +llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, + LLVMContext &Context, SlotMapping *Slots, + bool UpgradeDebugInfo, StringRef DataLayoutString) { ErrorOr> FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = FileOrErr.getError()) { @@ -57,16 +60,16 @@ } return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots, - UpgradeDebugInfo); + UpgradeDebugInfo, DataLayoutString); } -std::unique_ptr llvm::parseAssemblyString(StringRef AsmString, - SMDiagnostic &Err, - LLVMContext &Context, - SlotMapping *Slots, - bool UpgradeDebugInfo) { +std::unique_ptr +llvm::parseAssemblyString(StringRef AsmString, SMDiagnostic &Err, + LLVMContext &Context, SlotMapping *Slots, + bool UpgradeDebugInfo, StringRef DataLayoutString) { MemoryBufferRef F(AsmString, ""); - return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo); + return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo, + DataLayoutString); } Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err, Index: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp +++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp @@ -237,7 +237,7 @@ dyn_cast_or_null(In.getCurrentNode())) { SMDiagnostic Error; M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error, - Context, &IRSlots); + Context, &IRSlots, /*UpgradeDebugInfo=*/false); if (!M) { reportDiagnostic(diagFromBlockStringDiag(Error, BSN->getSourceRange())); return nullptr; Index: llvm/trunk/lib/IRReader/IRReader.cpp =================================================================== --- llvm/trunk/lib/IRReader/IRReader.cpp +++ llvm/trunk/lib/IRReader/IRReader.cpp @@ -68,7 +68,8 @@ std::unique_ptr llvm::parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err, LLVMContext &Context, - bool UpgradeDebugInfo) { + bool UpgradeDebugInfo, + StringRef DataLayoutString) { NamedRegionTimer T(TimeIRParsingName, TimeIRParsingDescription, TimeIRParsingGroupName, TimeIRParsingGroupDescription, TimePassesIsEnabled); @@ -83,15 +84,19 @@ }); return nullptr; } + if (!DataLayoutString.empty()) + ModuleOrErr.get()->setDataLayout(DataLayoutString); return std::move(ModuleOrErr.get()); } - return parseAssembly(Buffer, Err, Context, nullptr, UpgradeDebugInfo); + return parseAssembly(Buffer, Err, Context, nullptr, UpgradeDebugInfo, + DataLayoutString); } std::unique_ptr llvm::parseIRFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, - bool UpgradeDebugInfo) { + bool UpgradeDebugInfo, + StringRef DataLayoutString) { ErrorOr> FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = FileOrErr.getError()) { @@ -101,7 +106,7 @@ } return parseIR(FileOrErr.get()->getMemBufferRef(), Err, Context, - UpgradeDebugInfo); + UpgradeDebugInfo, DataLayoutString); } //===----------------------------------------------------------------------===// Index: llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll =================================================================== --- llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll +++ llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-0.ll @@ -2,7 +2,9 @@ target datalayout = "A1" -; CHECK: :7:41: error: address space must match datalayout +; CHECK: Allocation instruction pointer not in the stack address space! +; CHECK-NEXT: %alloca_scalar_no_align = alloca i32, addrspace(2) + define void @use_alloca() { %alloca_scalar_no_align = alloca i32, addrspace(2) ret void Index: llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll =================================================================== --- llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll +++ llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-1.ll @@ -2,7 +2,9 @@ target datalayout = "A1" -; CHECK: :7:50: error: address space must match datalayout +; CHECK: Allocation instruction pointer not in the stack address space! +; CHECK-NEXT: %alloca_scalar_no_align = alloca i32, align 4, addrspace(2) + define void @use_alloca() { %alloca_scalar_no_align = alloca i32, align 4, addrspace(2) ret void Index: llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll =================================================================== --- llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll +++ llvm/trunk/test/Assembler/datalayout-alloca-addrspace-mismatch-2.ll @@ -2,7 +2,9 @@ target datalayout = "A1" -; CHECK: :7:50: error: address space must match datalayout +; CHECK: Allocation instruction pointer not in the stack address space! +; CHECK-NEXT: %alloca_scalar_no_align = alloca i32, align 4, addrspace(2), !foo !0 + define void @use_alloca() { %alloca_scalar_no_align = alloca i32, align 4, addrspace(2), !foo !0 ret void Index: llvm/trunk/test/Assembler/drop-debug-info-nonzero-alloca.ll =================================================================== --- llvm/trunk/test/Assembler/drop-debug-info-nonzero-alloca.ll +++ llvm/trunk/test/Assembler/drop-debug-info-nonzero-alloca.ll @@ -0,0 +1,25 @@ +; RUN: llvm-as < %s -o %t.bc -data-layout=A5 2>&1 | FileCheck -check-prefixes=COM,AS %s +; RUN: llvm-dis < %t.bc | FileCheck -check-prefixes=COM,DIS %s +; RUN: opt < %s -S -data-layout=A5 2>&1 | FileCheck -check-prefixes=COM,AS %s +; RUN: opt < %t.bc -S | FileCheck -check-prefixes=COM,DIS %s + +define void @foo() { +entry: +; DIS: target datalayout = "A5" +; DIS: %tmp = alloca i32, addrspace(5) + %tmp = alloca i32, addrspace(5) + call void @llvm.dbg.value( + metadata i8* undef, + metadata !DILocalVariable(scope: !1), + metadata !DIExpression()) +; COM-NOT: Allocation instruction pointer not in the stack address space! +; AS: llvm.dbg.value intrinsic requires a !dbg attachment +; AS: warning: ignoring invalid debug info in +ret void +} + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.module.flags = !{!0} +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = distinct !DISubprogram(name: "foo") Index: llvm/trunk/test/CodeGen/AMDGPU/alloca.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/alloca.ll +++ llvm/trunk/test/CodeGen/AMDGPU/alloca.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as -data-layout=A5 < %s | llvm-dis | FileCheck %s +; RUN: llc -mtriple amdgcn-amd-amdhsa-amdgiz < %s +; RUN: llvm-as -data-layout=A5 < %s | llc -mtriple amdgcn-amd-amdhsa-amdgiz +; RUN: opt -data-layout=A5 -S < %s +; RUN: llvm-as -data-layout=A5 < %s | opt -S + +; CHECK: %tmp = alloca i32, addrspace(5) +define amdgpu_kernel void @test() { + %tmp = alloca i32, addrspace(5) + ret void +} + Index: llvm/trunk/test/CodeGen/AMDGPU/fence-barrier.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/fence-barrier.ll +++ llvm/trunk/test/CodeGen/AMDGPU/fence-barrier.ll @@ -1,4 +1,5 @@ -; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -enable-si-insert-waitcnts=1 -verify-machineinstrs < %s | FileCheck --check-prefix=GCN %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa-amdgiz -mcpu=gfx803 -enable-si-insert-waitcnts=1 -verify-machineinstrs < %s | FileCheck --check-prefix=GCN %s +; RUN: llvm-as -data-layout=A5 < %s | llc -mtriple=amdgcn-amd-amdhsa-amdgiz -mcpu=gfx803 -enable-si-insert-waitcnts=1 -verify-machineinstrs | FileCheck --check-prefix=GCN %s declare i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr() declare i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr() @@ -16,8 +17,8 @@ ; GCN-NEXT: s_barrier ; GCN: flat_store_dword define amdgpu_kernel void @test_local(i32 addrspace(1)*) { - %2 = alloca i32 addrspace(1)*, align 4 - store i32 addrspace(1)* %0, i32 addrspace(1)** %2, align 4 + %2 = alloca i32 addrspace(1)*, align 4, addrspace(5) + store i32 addrspace(1)* %0, i32 addrspace(1)* addrspace(5)* %2, align 4 %3 = call i32 @llvm.amdgcn.workitem.id.x() %4 = zext i32 %3 to i64 %5 = icmp eq i64 %4, 0 @@ -32,7 +33,7 @@ call void @llvm.amdgcn.s.barrier() fence syncscope("workgroup") acquire %8 = load i32, i32 addrspace(3)* getelementptr inbounds ([1 x i32], [1 x i32] addrspace(3)* @test_local.temp, i64 0, i64 0), align 4 - %9 = load i32 addrspace(1)*, i32 addrspace(1)** %2, align 4 + %9 = load i32 addrspace(1)*, i32 addrspace(1)* addrspace(5)* %2, align 4 %10 = call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr() %11 = call i32 @llvm.amdgcn.workitem.id.x() %12 = call i32 @llvm.amdgcn.workgroup.id.x() @@ -58,14 +59,14 @@ ; GCN: s_waitcnt vmcnt(0) lgkmcnt(0){{$}} ; GCN-NEXT: s_barrier define amdgpu_kernel void @test_global(i32 addrspace(1)*) { - %2 = alloca i32 addrspace(1)*, align 4 - %3 = alloca i32, align 4 - store i32 addrspace(1)* %0, i32 addrspace(1)** %2, align 4 - store i32 0, i32* %3, align 4 + %2 = alloca i32 addrspace(1)*, align 4, addrspace(5) + %3 = alloca i32, align 4, addrspace(5) + store i32 addrspace(1)* %0, i32 addrspace(1)* addrspace(5)* %2, align 4 + store i32 0, i32 addrspace(5)* %3, align 4 br label %4 ;