Skip to content

[RISCV] Add support for RISC-V Pointer Masking #79929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 5, 2024

Conversation

michaelmaitland
Copy link
Contributor

This patch implements the v0.8.1 specification. This patch reports version 0.8 in llvm since RISCVISAInfo::ExtensionVersion only has a Major and Minor version number. This patch includes includes support of the Ssnpm, Smnpm, Smmpm, Sspm and Supm extensions that make up RISC-V pointer masking.

All of these extensions 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

@llvmbot llvmbot added clang Clang issues not falling into any other category llvm:support labels Jan 30, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 30, 2024

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-llvm-support

@llvm/pr-subscribers-backend-risc-v

Author: Michael Maitland (michaelmaitland)

Changes

This patch implements the v0.8.1 specification. This patch reports version 0.8 in llvm since RISCVISAInfo::ExtensionVersion only has a Major and Minor version number. This patch includes includes support of the Ssnpm, Smnpm, Smmpm, Sspm and Supm extensions that make up RISC-V pointer masking.

All of these extensions 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


Full diff: https://github.com/llvm/llvm-project/pull/79929.diff

7 Files Affected:

  • (modified) clang/test/Preprocessor/riscv-target-features.c (+45)
  • (modified) llvm/docs/RISCVUsage.rst (+3)
  • (modified) llvm/docs/ReleaseNotes.rst (+1)
  • (modified) llvm/lib/Support/RISCVISAInfo.cpp (+6)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+34)
  • (modified) llvm/test/CodeGen/RISCV/attributes.ll (+20)
  • (modified) llvm/unittests/Support/RISCVISAInfoTest.cpp (+5)
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)";

Copy link
Contributor

@jaidTw jaidTw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you also update the riscv32-toolchain-extra.c and riscv64-toolchain-extra.c?
LGTM otherwise

@michaelmaitland
Copy link
Contributor Author

Should you also update the riscv32-toolchain-extra.c and riscv64-toolchain-extra.c?

It is not immediately obvious to me what you had in mind for changing those tests. Could you please clarify?

@jaidTw
Copy link
Contributor

jaidTw commented Feb 2, 2024

Should you also update the riscv32-toolchain-extra.c and riscv64-toolchain-extra.c?

It is not immediately obvious to me what you had in mind for changing those tests. Could you please clarify?

I found I messed up the configuration so there were some test errors on my end. It works after I fixed it, never mind

// present.
def FeatureStdExtSsnpm
: SubtargetFeature<"experimental-ssnpm", "HasStdExtSsnpm", "true",
"'Ssnpm' (Supervisor-level Pointer Masking)">;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add "for Next Lower Privilege Level" to ssnpm and smnpm description. I think that's important and the meaning of the 'n' in the extension name.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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
@topperc
Copy link
Collaborator

topperc commented Feb 5, 2024

Looks like we missed updating llvm/test/MC/RISCV/attribute-arch.s

michaelmaitland added a commit to michaelmaitland/llvm-project that referenced this pull request Feb 5, 2024
agozillon pushed a commit to agozillon/llvm-project that referenced this pull request Feb 5, 2024
This patch implements the v0.8.1 specification. This patch reports
version 0.8 in llvm since `RISCVISAInfo::ExtensionVersion` only has a
`Major` and `Minor` version number. This patch includes includes support
of the `Ssnpm`, `Smnpm`, `Smmpm`, `Sspm` and `Supm` extensions that make
up RISC-V pointer masking.

All of these extensions 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
michaelmaitland added a commit that referenced this pull request Feb 5, 2024
ichaer added a commit to ichaer/llvm-project-onesided_lower_bound that referenced this pull request Feb 12, 2024
* llvm/main: (328 commits)
  [Flang][OpenMP] Attempt to make map-types-and-sizes.f90 test more agnostic to other architectures
  [Transforms] Add more cos combinations to SimplifyLibCalls and InstCombine (llvm#79699)
  [workflows] Close issues used for backports once the PR has been created (llvm#80394)
  [RISCV] Add support for RISC-V Pointer Masking (llvm#79929)
  [lldb] Cleanup regex in libcxx formatters (NFC) (llvm#80618)
  [lldb] Remove unused private TypeCategoryMap methods (NFC) (llvm#80602)
  [mlir][sparse] refine sparse assembler strategy (llvm#80521)
  [NFC] Fix typo (llvm#80703)
  Fix broken ARM processor features test (llvm#80717)
  [ValueTracking][NFC] Pass `SimplifyQuery` to `computeKnownFPClass` family (llvm#80657)
  [x86_64][windows][swift] do not use Swift async extended frame for wi… (llvm#80468)
  [X86] addConstantComments - add FP16 MOVSH asm comments support
  [X86] Regenerate some vector constant comments missed in recent patches to improve mask predicate handling in addConstantComments
  [clang][AMDGPU][CUDA] Handle __builtin_printf for device printf (llvm#68515)
  Add some clarification to email check message
  [GitHub][Workflows] Prevent multiple private email comments (temporarily) (llvm#80648)
  [workflows] Use /mnt as the build directory on Linux (llvm#80583)
  [Flang][OpenMP] Initial mapping of Fortran pointers and allocatables for target devices (llvm#71766)
  [AMDGPU] GlobalISel for f8 conversions (llvm#80503)
  [AMDGPU] Fixed byte_sel of v_cvt_f32_bf8/v_cvt_f32_fp8 (llvm#80502)
  ...
michaelmaitland added a commit that referenced this pull request Jun 27, 2024
These extensions had their version number bumped and still experimental
(under public review). I didn't see anything in the [commit
history](https://github.com/riscv/riscv-j-extension/commits/master/)
since #79929 that would warrant a change to the implementation of
pointer masking in the compiler.
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
These extensions had their version number bumped and still experimental
(under public review). I didn't see anything in the [commit
history](https://github.com/riscv/riscv-j-extension/commits/master/)
since llvm#79929 that would warrant a change to the implementation of
pointer masking in the compiler.
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
These extensions had their version number bumped and still experimental
(under public review). I didn't see anything in the [commit
history](https://github.com/riscv/riscv-j-extension/commits/master/)
since llvm#79929 that would warrant a change to the implementation of
pointer masking in the compiler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V clang Clang issues not falling into any other category llvm:support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants