From f850035493e6f055182b443083a04a1d80bfd5c8 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 8 Dec 2022 20:31:44 +0000 Subject: [PATCH] [LLParser] Support symbolic address space numbers This allows the LLParser to also accept "A", "G", and "P" in `addrspace` usages. "A" will be replaced by the alloca address space defined in the globals, "G" by the default globals address space and "P" by the program address space. This makes it easier to write tests that use different address space and only only vary the RUN: lines. Currently, the only alternative is to pre-process the sources with a tool such as `sed` Importantly, these new string values are only accepted in .ll files and not stored in the bitcode format, so it does not round-trip via llvm-as and llvm-dis (see newly added test). Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D138789 --- llvm/docs/LangRef.rst | 5 +++ llvm/lib/AsmParser/LLParser.cpp | 23 +++++++++- llvm/test/Assembler/symbolic-addrspace.ll | 73 +++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Assembler/symbolic-addrspace.ll diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index c5c2f62..610cebc 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3590,6 +3590,11 @@ commonly used to reference objects in memory. Pointer types may have an optional address space attribute defining the numbered address space where the pointed-to object resides. For example, ``ptr addrspace(5)`` is a pointer to address space 5. +In addition to integer constants, ``addrspace`` can also reference one of the +address spaces defined in the :ref:`datalayout string`. +``addrspace("A")`` will use the alloca address space, ``addrspace("G")`` +the default globals address space and ``addrspace("P")`` the program address +space. The default address space is number zero. diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f02e8cb..866243c7 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1787,8 +1787,29 @@ bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) { AddrSpace = DefaultAS; if (!EatIfPresent(lltok::kw_addrspace)) return false; + + auto ParseAddrspaceValue = [&](unsigned &AddrSpace) -> bool { + if (Lex.getKind() == lltok::StringConstant) { + auto AddrSpaceStr = Lex.getStrVal(); + if (AddrSpaceStr == "A") { + AddrSpace = M->getDataLayout().getAllocaAddrSpace(); + } else if (AddrSpaceStr == "G") { + AddrSpace = M->getDataLayout().getDefaultGlobalsAddressSpace(); + } else if (AddrSpaceStr == "P") { + AddrSpace = M->getDataLayout().getProgramAddressSpace(); + } else { + return tokError("invalid symbolic addrspace '" + AddrSpaceStr + "'"); + } + Lex.Lex(); + return false; + } else if (Lex.getKind() != lltok::APSInt) { + return tokError("expected integer or string constant"); + } + return parseUInt32(AddrSpace); + }; + return parseToken(lltok::lparen, "expected '(' in address space") || - parseUInt32(AddrSpace) || + ParseAddrspaceValue(AddrSpace) || parseToken(lltok::rparen, "expected ')' in address space"); } diff --git a/llvm/test/Assembler/symbolic-addrspace.ll b/llvm/test/Assembler/symbolic-addrspace.ll new file mode 100644 index 0000000..7cdfb7c --- /dev/null +++ b/llvm/test/Assembler/symbolic-addrspace.ll @@ -0,0 +1,73 @@ +;; Check that we can parse symbolic addres space constants "A", "G", "P". +;; NB: These do not round-trip via llvm-as, they are purely for initial parsing +;; and will be converted to a numerical constant that does not depend on the +;; datalayout by the .ll parser. +; RUN: split-file %s %t --leading-lines +; RUN: llvm-as < %t/valid.ll | llvm-dis | FileCheck %s +; RUN: llvm-as < %t/alloca-in-other-as.ll | llvm-dis | FileCheck %s --check-prefix ALLOCA-IN-GLOBALS +; RUN: not llvm-as < %t/bad-not-string.ll 2>&1 | FileCheck %s --check-prefix=ERR-NOT-STR +; RUN: not llvm-as < %t/bad-unknown-char.ll 2>&1 | FileCheck %s --check-prefix=ERR-BAD-CHAR +; RUN: not llvm-as < %t/bad-multiple-valid-chars.ll 2>&1 | FileCheck %s --check-prefix=ERR-MULTIPLE-CHARS +; RUN: not llvm-as < %t/bad-using-at-symbol.ll 2>&1 | FileCheck %s --check-prefix=ERR-AT-SYMBOL +; RUN: not llvm-as < %t/bad-number-in-quotes.ll 2>&1 | FileCheck %s --check-prefix=ERR-NUMBER-IN-QUOTES + +;--- valid.ll +target datalayout = "A1-G2-P3" +; CHECK: target datalayout = "A1-G2-P3" + +; CHECK: @str = private addrspace(2) constant [4 x i8] c"str\00" +@str = private addrspace("G") constant [4 x i8] c"str\00" + +define void @foo() { + ; CHECK: %alloca = alloca i32, align 4, addrspace(1) + %alloca = alloca i32, addrspace("A") + ret void +} + +; CHECK: define void @bar() addrspace(3) { +define void @bar() addrspace("P") { + ; CHECK: call addrspace(3) void @foo() + call addrspace("P") void @foo() + ret void +} + +;--- alloca-in-other-as.ll +target datalayout = "A1-G2-P3" +; ALLOCA-IN-GLOBALS: target datalayout = "A1-G2-P3" + +define void @foo() { + ; ALLOCA-IN-GLOBALS: %alloca = alloca i32, align 4, addrspace(2){{$}} + ; ALLOCA-IN-GLOBALS: %alloca2 = alloca i32, align 4, addrspace(1){{$}} + ; ALLOCA-IN-GLOBALS: %alloca3 = alloca i32, align 4{{$}} + ; ALLOCA-IN-GLOBALS: %alloca4 = alloca i32, align 4, addrspace(3){{$}} + %alloca = alloca i32, addrspace("G") + %alloca2 = alloca i32, addrspace("A") + %alloca3 = alloca i32 + %alloca4 = alloca i32, addrspace("P") + ret void +} + +;--- bad-not-string.ll +target datalayout = "G2" +@str = private addrspace(D) constant [4 x i8] c"str\00" +; ERR-NOT-STR: [[#@LINE-1]]:26: error: expected integer or string constant + +;--- bad-unknown-char.ll +target datalayout = "G2" +@str = private addrspace("D") constant [4 x i8] c"str\00" +; ERR-BAD-CHAR: [[#@LINE-1]]:26: error: invalid symbolic addrspace 'D' + +;--- bad-multiple-valid-chars.ll +target datalayout = "A1-G2" +@str = private addrspace("AG") constant [4 x i8] c"str\00" +; ERR-MULTIPLE-CHARS: [[#@LINE-1]]:26: error: invalid symbolic addrspace 'AG' + +;--- bad-using-at-symbol.ll +target datalayout = "A1-G2" +@str = private addrspace(@A) constant [4 x i8] c"str\00" +; ERR-AT-SYMBOL: [[#@LINE-1]]:26: error: expected integer or string constant + +;--- bad-number-in-quotes.ll +target datalayout = "A1-G2" +@str = private addrspace("10") constant [4 x i8] c"str\00" +; ERR-NUMBER-IN-QUOTES: [[#@LINE-1]]:26: error: invalid symbolic addrspace '10' -- 2.7.4