[llvm] f850035 - [LLParser] Support symbolic address space numbers

Alex Richardson via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 8 12:52:10 PST 2022


Author: Alex Richardson
Date: 2022-12-08T20:44:40Z
New Revision: f850035493e6f055182b443083a04a1d80bfd5c8

URL: https://github.com/llvm/llvm-project/commit/f850035493e6f055182b443083a04a1d80bfd5c8
DIFF: https://github.com/llvm/llvm-project/commit/f850035493e6f055182b443083a04a1d80bfd5c8.diff

LOG: [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

Added: 
    llvm/test/Assembler/symbolic-addrspace.ll

Modified: 
    llvm/docs/LangRef.rst
    llvm/lib/AsmParser/LLParser.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index c5c2f62cfb013..610cebced1781 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<langref_datalayout>`.
+``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 f02e8cb52d1fe..866243c75864e 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 0000000000000..7cdfb7cce1e93
--- /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"
+ at 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"
+ at 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"
+ at 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"
+ at 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"
+ at 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"
+ at str = private addrspace("10") constant [4 x i8] c"str\00"
+; ERR-NUMBER-IN-QUOTES: [[#@LINE-1]]:26: error: invalid symbolic addrspace '10'


        


More information about the llvm-commits mailing list