Skip to content

Commit

Permalink
[RISCV] Add support for RISC-V Pointer Masking (#79929)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
michaelmaitland committed Feb 5, 2024
1 parent 0c02ea0 commit 0bf165e
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 0 deletions.
45 changes: 45 additions & 0 deletions clang/test/Preprocessor/riscv-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {{.*$}}
Expand Down Expand Up @@ -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 \
Expand Down
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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>`_.

Expand Down
1 change: 1 addition & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------------------------------
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}},
Expand Down
34 changes: 34 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down
20 changes: 20 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions llvm/unittests/Support/RISCVISAInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)";
Expand Down

0 comments on commit 0bf165e

Please sign in to comment.