[llvm] [clang] [RISCV] Add support for RISC-V Pointer Masking (PR #79929)

Michael Maitland via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 4 14:47:51 PST 2024


https://github.com/michaelmaitland updated https://github.com/llvm/llvm-project/pull/79929

>From bc844fb4e033063c0d7b5ab361c44e4823e76fa3 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 29 Jan 2024 12:33:59 -0800
Subject: [PATCH 1/3] [RISCV] Add support for RISC-V Pointer Masking

This patch implements the v0.8.1 specification. This includes support of
the `Ssnpm`, `Smnpm`, `Smmpm`, `Sspm` and `Supm` extensions that make up
RISC-V pointer masking.

All of these extensions only require emitting attribute containing
correct `march` string. `Ssnpm`, `Smnpm`, `Smmpm` extensions introduce a
2-bit WARL field (PMM). The extension does not specify how PMM is set,
and therefore this patch does not need to address this. One example of
how it *could* be set is using the Zicsr instructions to update the PMM
bits of the described registers.

The full specification can be found at
https://github.com/riscv/riscv-j-extension/blob/master/zjpm-spec.pdf
---
 .../test/Preprocessor/riscv-target-features.c | 45 +++++++++++++++++++
 llvm/docs/RISCVUsage.rst                      |  3 ++
 llvm/docs/ReleaseNotes.rst                    |  1 +
 llvm/lib/Support/RISCVISAInfo.cpp             |  6 +++
 llvm/lib/Target/RISCV/RISCVFeatures.td        | 34 ++++++++++++++
 llvm/test/CodeGen/RISCV/attributes.ll         | 20 +++++++++
 llvm/unittests/Support/RISCVISAInfoTest.cpp   |  5 +++
 7 files changed, 114 insertions(+)

diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 2361c83a5a610..82d2efd51a091 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -142,6 +142,11 @@
 
 // Experimental extensions
 
+// CHECK-NOT: __riscv_smmpm{{.*$}}
+// CHECK-NOT: __riscv_smnpm{{.*$}}
+// CHECK-NOT: __riscv_ssnpm{{.*$}}
+// CHECK-NOT: __riscv_sspm{{.*$}}
+// CHECK-NOT: __riscv_supm{{.*$}}
 // CHECK-NOT: __riscv_zaamo {{.*$}}
 // CHECK-NOT: __riscv_zacas {{.*$}}
 // CHECK-NOT: __riscv_zalrsc {{.*$}}
@@ -1405,6 +1410,46 @@
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZICFISS-EXT %s
 // CHECK-ZICFISS-EXT: __riscv_zicfiss 4000{{$}}
 
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_ssnpm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SSNPM-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_ssnpm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SSNPM-EXT %s
+// CHECK-SSNPM-EXT: __riscv_ssnpm 8000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_smnpm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SMNPM-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_smnpm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SMNPM-EXT %s
+// CHECK-SMNPM-EXT: __riscv_smnpm 8000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_smmpm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SMMPM-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_smmpm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SMMPM-EXT %s
+// CHECK-SMMPM-EXT: __riscv_smmpm 8000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_sspm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SSPM-EXT %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_sspm0p8 -E -dM %s -menable-experimental-extensions \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SSPM-EXT %s
+// CHECK-SSPM-EXT: __riscv_sspm 8000{{$}}
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_supm0p8 -E -dM %s \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SUPM-EXT %s
+// RUN: %clang --target=riscv64 \
+// RUN:   -march=rv64i_supm0p8 -E -dM %s -menable-experimental-extensions \
+// RUN:   -o - | FileCheck --check-prefix=CHECK-SUPM-EXT %s
+// CHECK-SUPM-EXT: __riscv_supm 8000{{$}}
+
 // Misaligned
 
 // RUN: %clang --target=riscv32-unknown-linux-gnu -march=rv32i -E -dM %s \
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 06292f05b90b8..d07f0480f7024 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -226,6 +226,9 @@ LLVM supports (to various degrees) a number of experimental extensions.  All exp
 
 The primary goal of experimental support is to assist in the process of ratification by providing an existence proof of an implementation, and simplifying efforts to validate the value of a proposed extension against large code bases.  Experimental extensions are expected to either transition to ratified status, or be eventually removed.  The decision on whether to accept an experimental extension is currently done on an entirely case by case basis; if you want to propose one, attending the bi-weekly RISC-V sync-up call is strongly advised.
 
+``Ssnpm``, ``Smnpm``, ``Smmpm``, ``Sspm``, ``Supm``
+  LLVM implements the `v0.8.1 draft specification <https://github.com/riscv/riscv-j-extension/blob/master/zjpm-spec.pdf>
+
 ``experimental-zacas``
   LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.
 
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 15eb2408310a5..d7fb05d100828 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -93,6 +93,7 @@ Changes to the RISC-V Backend
 -----------------------------
 
 * Support for the Zicond extension is no longer experimental.
+* The experimental Ssnpm, Smnpm, Smmpm, Sspm, and Supm 0.8.1 Pointer Masking extensions are supported.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index c46d76da962c6..a42c4a506652f 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -193,6 +193,12 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
 // NOTE: This table should be sorted alphabetically by extension name.
 // clang-format off
 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
+    {"smmpm", {0, 8}},
+    {"smnpm", {0, 8}},
+    {"ssnpm", {0, 8}},
+    {"sspm", {0, 8}},
+    {"supm", {0, 8}},
+
     {"zaamo", {0, 2}},
     {"zacas", {1, 0}},
     {"zalrsc", {0, 2}},
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 58bf5e8fdefbd..9a6cf9e220d69 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -797,6 +797,40 @@ def FeatureStdExtSvpbmt
     : SubtargetFeature<"svpbmt", "HasStdExtSvpbmt", "true",
                        "'Svpbmt' (Page-Based Memory Types)">;
 
+// Pointer Masking extensions
+
+// A supervisor-level extension that provides pointer masking for the next lower
+// privilege mode (U-mode), and for VS- and VU-modes if the H extension is
+// present.
+def FeatureStdExtSsnpm
+    : SubtargetFeature<"experimental-ssnpm", "HasStdExtSsnpm", "true",
+                       "'Ssnpm' (Supervisor-level Pointer Masking)">;
+
+// A machine-level extension that provides pointer masking for the next lower
+// privilege mode (S/HS if S-mode is implemented, or U-mode otherwise).
+def FeatureStdExtSmnpm
+    : SubtargetFeature<"experimental-smnpm", "HasStdExtSmnpm", "true",
+                       "'Smnpm' (Machine-level Pointer Masking)">;
+
+// A machine-level extension that provides pointer masking for M-mode.
+def FeatureStdExtSmmpm
+    : SubtargetFeature<"experimental-smmpm", "HasStdExtSmmpm", "true",
+                       "'Smmpm' (Machine-level Pointer Masking for M-mode)">;
+
+// An extension that indicates that there is pointer-masking support available
+// in supervisor mode, with some facility provided in the supervisor execution
+// environment to control pointer masking.
+def FeatureStdExtSspm
+    : SubtargetFeature<"experimental-sspm", "HasStdExtSspm", "true",
+                       "'Sspm' (Indicates Supervisor-mode Pointer Masking)">;
+
+// An extension that indicates that there is pointer-masking support available
+// in user mode, with some facility provided in the application execution
+// environment to control pointer masking.
+def FeatureStdExtSupm
+    : SubtargetFeature<"experimental-supm", "HasStdExtSupm", "true",
+                       "'Supm' (Indicates User-mode Pointer Masking)">;
+
 //===----------------------------------------------------------------------===//
 // Vendor extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index b64db86ddf6c7..b64e305db9457 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -97,6 +97,11 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV32ZACAS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV32ZICFILP %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-ssnpm  %s -o - | FileCheck --check-prefix=RV32SSNPM %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-smnpm  %s -o - | FileCheck --check-prefix=RV32SMNPM %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-smmpm %s -o - | FileCheck --check-prefix=RV32SMMPM %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-sspm %s -o - | FileCheck --check-prefix=RV32SSPM %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-supm %s -o - | FileCheck --check-prefix=RV32SUPM %s
 
 ; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s
 ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s
@@ -201,6 +206,11 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV64ZALRSC %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV64ZICFILP %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-ssnpm  %s -o - | FileCheck --check-prefix=RV64SSNPM %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-smnpm  %s -o - | FileCheck --check-prefix=RV64SMNPM %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-smmpm %s -o - | FileCheck --check-prefix=RV64SMMPM %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-sspm %s -o - | FileCheck --check-prefix=RV64SSPM %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-supm %s -o - | FileCheck --check-prefix=RV64SUPM %s
 
 ; CHECK: .attribute 4, 16
 
@@ -300,6 +310,11 @@
 ; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc0p2"
 ; RV32ZICFILP: .attribute 5, "rv32i2p1_zicfilp0p4"
+; RV32SSNPM: .attribute 5, "rv32i2p1_ssnpm0p8"
+; RV32SMNPM: .attribute 5, "rv32i2p1_smnpm0p8"
+; RV32SMMPM: .attribute 5, "rv32i2p1_smmpm0p8"
+; RV32SSPM: .attribute 5, "rv32i2p1_sspm0p8"
+; RV32SUPM: .attribute 5, "rv32i2p1_supm0p8"
 
 ; RV64M: .attribute 5, "rv64i2p1_m2p0"
 ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -403,6 +418,11 @@
 ; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0"
 ; RV64ZALRSC: .attribute 5, "rv64i2p1_zalrsc0p2"
 ; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p4"
+; RV64SSNPM: .attribute 5, "rv64i2p1_ssnpm0p8"
+; RV64SMNPM: .attribute 5, "rv64i2p1_smnpm0p8"
+; RV64SMMPM: .attribute 5, "rv64i2p1_smmpm0p8"
+; RV64SSPM: .attribute 5, "rv64i2p1_sspm0p8"
+; RV64SUPM: .attribute 5, "rv64i2p1_supm0p8"
 
 define i32 @addi(i32 %a) {
   %1 = add i32 %a, 1
diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp
index f03ccecfae799..3929161c4e409 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -799,6 +799,11 @@ Experimental extensions
     ztso                0.1
     zvfbfmin            1.0
     zvfbfwma            1.0
+    smmpm               0.8
+    smnpm               0.8
+    ssnpm               0.8
+    sspm                0.8
+    supm                0.8
 
 Use -march to specify the target's extension.
 For example, clang -march=rv32i_v1p0)";

>From 2bb6d4efefc9a000ea3878a90d5c1dcd8671cd3d Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Mon, 29 Jan 2024 17:47:51 -0800
Subject: [PATCH 2/3] fixup! add backtick in docs

---
 llvm/docs/RISCVUsage.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index d07f0480f7024..0a432c66bff94 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -227,7 +227,7 @@ LLVM supports (to various degrees) a number of experimental extensions.  All exp
 The primary goal of experimental support is to assist in the process of ratification by providing an existence proof of an implementation, and simplifying efforts to validate the value of a proposed extension against large code bases.  Experimental extensions are expected to either transition to ratified status, or be eventually removed.  The decision on whether to accept an experimental extension is currently done on an entirely case by case basis; if you want to propose one, attending the bi-weekly RISC-V sync-up call is strongly advised.
 
 ``Ssnpm``, ``Smnpm``, ``Smmpm``, ``Sspm``, ``Supm``
-  LLVM implements the `v0.8.1 draft specification <https://github.com/riscv/riscv-j-extension/blob/master/zjpm-spec.pdf>
+  LLVM implements the `v0.8.1 draft specification <https://github.com/riscv/riscv-j-extension/blob/master/zjpm-spec.pdf>`
 
 ``experimental-zacas``
   LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.

>From 10d3a274b1967cd4b8197584b3a82d32ed83d073 Mon Sep 17 00:00:00 2001
From: Michael Maitland <michaeltmaitland at gmail.com>
Date: Sun, 4 Feb 2024 14:47:34 -0800
Subject: [PATCH 3/3] fixup! add meaning of n in description

---
 llvm/lib/Target/RISCV/RISCVFeatures.td | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 9a6cf9e220d69..90b4f06469931 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -804,13 +804,13 @@ def FeatureStdExtSvpbmt
 // present.
 def FeatureStdExtSsnpm
     : SubtargetFeature<"experimental-ssnpm", "HasStdExtSsnpm", "true",
-                       "'Ssnpm' (Supervisor-level Pointer Masking)">;
+                       "'Ssnpm' (Supervisor-level Pointer Masking for next lower privilege mode)">;
 
 // A machine-level extension that provides pointer masking for the next lower
 // privilege mode (S/HS if S-mode is implemented, or U-mode otherwise).
 def FeatureStdExtSmnpm
     : SubtargetFeature<"experimental-smnpm", "HasStdExtSmnpm", "true",
-                       "'Smnpm' (Machine-level Pointer Masking)">;
+                       "'Smnpm' (Machine-level Pointer Masking for next lower privilege mode)">;
 
 // A machine-level extension that provides pointer masking for M-mode.
 def FeatureStdExtSmmpm



More information about the cfe-commits mailing list