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

Michael Maitland via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 5 08:27:44 PST 2024


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

>From e5e34889db5d64e5b918f434f16408756e8cb90d 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] [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 f81ec7ac4532f..add96c0046cc7 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -159,6 +159,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_zalasr {{.*$}}
@@ -1567,6 +1572,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 e6d1f41849302..c9e99c9b98e37 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -243,6 +243,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.
 
+``experimental-ssnpm``, ``experimental-smnpm``, ``experimental-smmpm``, ``experimental-sspm``, ``experimental-supm``
+  LLVM implements the `v0.8.1 draft specification <https://github.com/riscv/riscv-j-extension/blob/master/zjpm-spec.pdf>`
+
 ``experimental-zabha``
   LLVM implements assembler support for the `v1.0-rc1 draft specification <https://github.com/riscv/riscv-zabha/tree/v1.0-rc1>`_.
 
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 89b999fcbfe9d..6ac83961d7cf0 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -101,6 +101,7 @@ Changes to the RISC-V Backend
 * The names of the majority of the S-prefixed (supervisor-level) extension
   names in the RISC-V profiles specification are now recognised.
 * Codegen support was added for the Zimop (May-Be-Operations) extension.
+* 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 b4fa20d202d3e..6fe8eb62e2804 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -211,6 +211,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}},
     {"zabha", {1, 0}},
     {"zacas", {1, 0}},
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index af7519cedca11..71119136379b3 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -876,6 +876,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 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 for next lower privilege mode)">;
+
+// 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 89b2190310f77..088cc0b90a05a 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -116,6 +116,11 @@
 ; 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-zabha %s -o - | FileCheck --check-prefix=RV32ZABHA %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
@@ -239,6 +244,11 @@
 ; 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-zabha %s -o - | FileCheck --check-prefix=RV64ZABHA %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
 
@@ -357,6 +367,11 @@
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc0p2"
 ; RV32ZICFILP: .attribute 5, "rv32i2p1_zicfilp0p4"
 ; RV32ZABHA: .attribute 5, "rv32i2p1_a2p1_zabha1p0"
+; 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"
@@ -479,6 +494,11 @@
 ; RV64ZALRSC: .attribute 5, "rv64i2p1_zalrsc0p2"
 ; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p4"
 ; RV64ZABHA: .attribute 5, "rv64i2p1_a2p1_zabha1p0"
+; 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 8f44c7ba69364..ac6066ebdfb94 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -881,6 +881,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)";



More information about the cfe-commits mailing list