[llvm] [clang] [RISCV][MC] MC layer support for the experimental zalasr extension (PR #69685)

Brendan Sweeney via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 25 14:55:08 PST 2024


https://github.com/mehnadnerd updated https://github.com/llvm/llvm-project/pull/69685

>From c5ade18c2d22fb9913331b3339955bf56e8c38ad Mon Sep 17 00:00:00 2001
From: brs <turtwig at utexas.edu>
Date: Thu, 19 Oct 2023 17:16:45 -0500
Subject: [PATCH 1/3] [RISCV][MC] MC layer support for the experimental zalasr
 extension

---
 .../test/Preprocessor/riscv-target-features.c |  9 ++
 llvm/docs/RISCVUsage.rst                      |  3 +
 llvm/lib/Support/RISCVISAInfo.cpp             |  1 +
 llvm/lib/Target/RISCV/RISCVFeatures.td        |  7 ++
 llvm/lib/Target/RISCV/RISCVInstrInfo.td       |  1 +
 llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td | 66 ++++++++++++++
 llvm/test/CodeGen/RISCV/attributes.ll         |  4 +
 llvm/test/MC/RISCV/attribute-arch.s           |  3 +
 llvm/test/MC/RISCV/rv32zalasr-invalid.s       | 40 ++++++++
 llvm/test/MC/RISCV/rv32zalasr-valid.s         | 70 ++++++++++++++
 llvm/test/MC/RISCV/rv64zalasr-invalid.s       | 28 ++++++
 llvm/test/MC/RISCV/rv64zalasr-valid.s         | 91 +++++++++++++++++++
 llvm/unittests/Support/RISCVISAInfoTest.cpp   |  1 +
 13 files changed, 324 insertions(+)
 create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
 create mode 100644 llvm/test/MC/RISCV/rv32zalasr-invalid.s
 create mode 100644 llvm/test/MC/RISCV/rv32zalasr-valid.s
 create mode 100644 llvm/test/MC/RISCV/rv64zalasr-invalid.s
 create mode 100644 llvm/test/MC/RISCV/rv64zalasr-valid.s

diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 8f50126f1b36285..55673f3feb130e1 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -145,6 +145,7 @@
 // CHECK-NOT: __riscv_zacas {{.*$}}
 // CHECK-NOT: __riscv_zalrsc {{.*$}}
 // CHECK-NOT: __riscv_zcmop {{.*$}}
+// CHECK-NOT: __riscv_zalasr {{.*$}}
 // CHECK-NOT: __riscv_zfbfmin {{.*$}}
 // CHECK-NOT: __riscv_zicfilp {{.*$}}
 // CHECK-NOT: __riscv_zicfiss {{.*$}}
@@ -1120,6 +1121,14 @@
 // RUN:   -o - | FileCheck --check-prefix=CHECK-SMEPMP-EXT %s
 // CHECK-SMEPMP-EXT: __riscv_smepmp  1000000{{$}}
 
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zalasr1p0 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zalasr1p0 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s
+// CHECK-ZALASR-EXT: __riscv_zalasr 1000000{{$}}
+
 // RUN: %clang --target=riscv32-unknown-linux-gnu \
 // RUN:   -march=rv32izfa -E -dM %s \
 // RUN:   -o - | FileCheck --check-prefix=CHECK-ZFA-EXT %s
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 2cfbb10abc8a1c3..1ac6f760fbad8fa 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -228,6 +228,9 @@ The primary goal of experimental support is to assist in the process of ratifica
 ``experimental-zacas``
   LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.
 
+``experimental-zalasr``
+  LLVM implements the `most recent specification <https://github.com/mehnadnerd/riscv-zalasr>`_.
+
 ``experimental-zfbfmin``, ``experimental-zvfbfmin``, ``experimental-zvfbfwma``
   LLVM implements assembler support for the `1.0.0-rc2 specification <https://github.com/riscv/riscv-bfloat16/releases/tag/v59042fc71c31a9bcb2f1957621c960ed36fac401>`_.
 
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index 32b4ff5de86f1ea..4c4eecde5da440e 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -195,6 +195,7 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
     {"zaamo", {0, 2}},
     {"zacas", {1, 0}},
     {"zalrsc", {0, 2}},
+    {"zalasr", {1, 0}},
 
     {"zcmop", {0, 2}},
 
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index c822b9c9c624001..db1b6c95909f60e 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -797,6 +797,13 @@ def FeatureStdExtSvpbmt
     : SubtargetFeature<"svpbmt", "HasStdExtSvpbmt", "true",
                        "'Svpbmt' (Page-Based Memory Types)">;
 
+def FeatureStdExtZalasr
+    : SubtargetFeature<"experimental-zalasr", "HasStdExtZalasr", "true",
+                       "'Zalasr' (Load-Acquire and Store-Release Instructions)">;
+def HasStdExtZalasr : Predicate<"Subtarget->hasStdExtZalasr()">,
+                               AssemblerPredicate<(all_of FeatureStdExtZalasr),
+                               "'Zalasr' (Load-Acquire and Store-Release Instructions)">;
+
 //===----------------------------------------------------------------------===//
 // Vendor extensions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 114329c2c7c5f38..8996ba3bc9f82be 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2144,6 +2144,7 @@ include "RISCVInstrInfoM.td"
 // Atomic
 include "RISCVInstrInfoA.td"
 include "RISCVInstrInfoZa.td"
+include "RISCVInstrInfoZalasr.td"
 
 // Scalar FP
 include "RISCVInstrInfoF.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
new file mode 100644
index 000000000000000..cb603bb60306295
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
@@ -0,0 +1,66 @@
+//===-- RISCVInstrInfoZalasr.td - RISC-V 'Zalasr' instructions -------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the RISC-V instructions from the Zalasr (Load-Acquire
+// and Store-Release) extension
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction class templates
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class LAQ_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
+    : RVInstRAtomic<0b00110, aq, rl, funct3, OPC_AMO,
+                    (outs GPR:$rd), (ins GPRMemZeroOffset:$rs1),
+                    opcodestr, "$rd, $rs1"> {
+  let rs2 = 0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class SRL_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
+    : RVInstRAtomic<0b00111, aq, rl, funct3, OPC_AMO,
+                    (outs ), (ins GPRMemZeroOffset:$rs1, GPR:$rs2),
+                    opcodestr, "$rs2, $rs1"> {
+  let rd = 0;
+}
+multiclass LAQ_r_aq_rl<bits<3> funct3, string opcodestr> {
+  def _AQ    : LAQ_r<1, 0, funct3, opcodestr # ".aq">;
+  def _AQ_RL : LAQ_r<1, 1, funct3, opcodestr # ".aqrl">;
+}
+
+multiclass SRL_r_aq_rl<bits<3> funct3, string opcodestr> {
+  def _RL    : SRL_r<0, 1, funct3, opcodestr # ".rl">;
+  def _AQ_RL : SRL_r<1, 1, funct3, opcodestr # ".aqrl">;
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+
+let Predicates = [HasStdExtZalasr] in {
+defm LB_AQ : LAQ_r_aq_rl<0b000, "lb">;
+defm LH_AQ : LAQ_r_aq_rl<0b001, "lh">;
+defm LW_AQ : LAQ_r_aq_rl<0b010, "lw">;
+defm SB_RL : SRL_r_aq_rl<0b000, "sb">;
+defm SH_RL : SRL_r_aq_rl<0b001, "sh">;
+defm SW_RL : SRL_r_aq_rl<0b010, "sw">;
+} // Predicates = [HasStdExtZalasr]
+
+let Predicates = [HasStdExtZalasr, IsRV64] in {
+defm LD_AQ : LAQ_r_aq_rl<0b011, "ld">;
+defm SD_RL : SRL_r_aq_rl<0b011, "sd">;
+} // Predicates = [HasStdExtZalasr, IsRV64]
+
+//===----------------------------------------------------------------------===//
+// Pseudo-instructions and codegen patterns
+//===----------------------------------------------------------------------===//
+
+// Future work: Work out mapping with leading/trailing fences, &c
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index ed1ab5a74f5c4f3..e1b47d964c73a0b 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -97,6 +97,7 @@
 ; 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-zalasr %s -o - | FileCheck --check-prefix=RV32ZALASR %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 +202,7 @@
 ; 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-zalasr %s -o - | FileCheck --check-prefix=RV64ZALASR %s
 
 ; CHECK: .attribute 4, 16
 
@@ -300,6 +302,7 @@
 ; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc0p2"
 ; RV32ZICFILP: .attribute 5, "rv32i2p1_zicfilp0p4"
+; RV32ZALASR: .attribute 5, "rv32i2p1_zalasr1p0"
 
 ; RV64M: .attribute 5, "rv64i2p1_m2p0"
 ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -403,6 +406,7 @@
 ; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0"
 ; RV64ZALRSC: .attribute 5, "rv64i2p1_zalrsc0p2"
 ; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p4"
+; RV64ZALASR: .attribute 5, "rv64i2p1_zalasr1p0"
 
 define i32 @addi(i32 %a) {
   %1 = add i32 %a, 1
diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index 5f9a7cabcc768ed..4d3c224f9e37d22 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -309,6 +309,9 @@
 .attribute arch, "rv32izacas1p0"
 # CHECK: attribute      5, "rv32i2p1_a2p1_zacas1p0"
 
+.attribute arch, "rv32izalasr1p0"
+# CHECK: attribute      5, "rv32i2p1_zalasr1p0"
+
 .attribute arch, "rv32i_xcvalu"
 # CHECK: attribute      5, "rv32i2p1_xcvalu1p0"
 
diff --git a/llvm/test/MC/RISCV/rv32zalasr-invalid.s b/llvm/test/MC/RISCV/rv32zalasr-invalid.s
new file mode 100644
index 000000000000000..3731c85cbc077f4
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zalasr-invalid.s
@@ -0,0 +1,40 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zalasr < %s 2>&1 | FileCheck -check-prefixes=CHECK %s
+
+# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
+ld.aq a1, (t0)
+
+# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
+ld.aqrl a1, (t0)
+
+# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
+sd.rl a1, (t0)
+
+# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
+sd.aqrl a1, (t0)
+
+# CHECK: error: unrecognized instruction mnemonic
+lw. a1, (t0)
+
+# CHECK: error: unrecognized instruction mnemonic
+lw.rl t3, 0(t5)
+
+# CHECK: error: unrecognized instruction mnemonic
+lh.rlaq t4, (t6)
+
+# CHECK: error: unrecognized instruction mnemonic
+sb. a1, (t0)
+
+# CHECK: error: unrecognized instruction mnemonic
+sh.aq t3, 0(t5)
+
+# CHECK: error: unrecognized instruction mnemonic
+sh.rlaq t4, (t6)
+
+# CHECK: error: optional integer offset must be 0
+lw.aq zero, 1(a0)
+
+# CHECK: error: optional integer offset must be 0
+sw.rl t1, 2(s0)
+
+# CHECK: error: optional integer offset must be 0
+sb.aqrl sp, 3(s2)
diff --git a/llvm/test/MC/RISCV/rv32zalasr-valid.s b/llvm/test/MC/RISCV/rv32zalasr-valid.s
new file mode 100644
index 000000000000000..fb85fbc00dfea2e
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zalasr-valid.s
@@ -0,0 +1,70 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zalasr -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zalasr < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zalasr -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+#
+# RUN: not llvm-mc -triple riscv32 \
+# RUN:     -riscv-no-aliases -show-encoding < %s 2>&1 \
+# RUN:     | FileCheck --check-prefixes=CHECK-NO-EXT %s
+
+# CHECK-ASM-AND-OBJ: lb.aq t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x03,0x05,0x34]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lb.aq t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: lh.aq t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x13,0x05,0x34]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lh.aq t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: lw.aq t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x23,0x05,0x34]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lw.aq t1, (a0)
+
+# CHECK-ASM-AND-OBJ: lb.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x03,0x05,0x36]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lb.aqrl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: lh.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x13,0x05,0x36]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lh.aqrl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: lw.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x23,0x05,0x36]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lw.aqrl t1, (a0)
+
+
+# CHECK-ASM-AND-OBJ: sb.rl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x00,0x65,0x3a]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sb.rl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: sh.rl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x10,0x65,0x3a]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sh.rl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: sw.rl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x20,0x65,0x3a]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sw.rl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: sb.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x00,0x65,0x3e]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sb.aqrl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: sh.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x10,0x65,0x3e]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sh.aqrl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: sw.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x20,0x65,0x3e]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sw.aqrl t1, 0(a0)
diff --git a/llvm/test/MC/RISCV/rv64zalasr-invalid.s b/llvm/test/MC/RISCV/rv64zalasr-invalid.s
new file mode 100644
index 000000000000000..032c0c00882cbf7
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zalasr-invalid.s
@@ -0,0 +1,28 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zalasr < %s 2>&1 | FileCheck -check-prefixes=CHECK %s
+
+# CHECK: error: unrecognized instruction mnemonic
+lw. a1, (t0)
+
+# CHECK: error: unrecognized instruction mnemonic
+lw.rl t3, 0(t5)
+
+# CHECK: error: unrecognized instruction mnemonic
+lh.rlaq t4, (t6)
+
+# CHECK: error: unrecognized instruction mnemonic
+sb. a1, (t0)
+
+# CHECK: error: unrecognized instruction mnemonic
+sh.aq t3, 0(t5)
+
+# CHECK: error: unrecognized instruction mnemonic
+sh.rlaq t4, (t6)
+
+# CHECK: error: optional integer offset must be 0
+lw.aq zero, 1(a0)
+
+# CHECK: error: optional integer offset must be 0
+sw.rl t1, 2(s0)
+
+# CHECK: error: optional integer offset must be 0
+sb.aqrl sp, 3(s2)
diff --git a/llvm/test/MC/RISCV/rv64zalasr-valid.s b/llvm/test/MC/RISCV/rv64zalasr-valid.s
new file mode 100644
index 000000000000000..9e623ccaaaf887f
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zalasr-valid.s
@@ -0,0 +1,91 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zalasr -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zalasr < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zalasr -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+#
+# RUN: not llvm-mc -triple riscv64 \
+# RUN:     -riscv-no-aliases -show-encoding < %s 2>&1 \
+# RUN:     | FileCheck --check-prefixes=CHECK-NO-EXT %s
+
+
+# CHECK-ASM-AND-OBJ: lb.aq t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x03,0x05,0x34]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lb.aq t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: lh.aq t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x13,0x05,0x34]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lh.aq t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: lw.aq t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x23,0x05,0x34]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lw.aq t1, (a0)
+
+# CHECK-ASM-AND-OBJ: ld.aq t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x33,0x05,0x34]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+ld.aq t1, (a0)
+
+# CHECK-ASM-AND-OBJ: lb.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x03,0x05,0x36]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lb.aqrl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: lh.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x13,0x05,0x36]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lh.aqrl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: lw.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x23,0x05,0x36]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+lw.aqrl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: ld.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x33,0x05,0x36]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+ld.aqrl t1, 0(a0)
+
+
+# CHECK-ASM-AND-OBJ: sb.rl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x00,0x65,0x3a]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sb.rl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: sh.rl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x10,0x65,0x3a]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sh.rl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: sw.rl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x20,0x65,0x3a]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sw.rl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: sd.rl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x30,0x65,0x3a]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sd.rl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: sb.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x00,0x65,0x3e]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sb.aqrl t1, (a0)
+
+# CHECK-ASM-AND-OBJ: sh.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x10,0x65,0x3e]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sh.aqrl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: sw.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x20,0x65,0x3e]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sw.aqrl t1, 0(a0)
+
+# CHECK-ASM-AND-OBJ: sd.aqrl t1, (a0)
+# CHECK-ASM: encoding: [0x2f,0x30,0x65,0x3e]
+# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
+sd.aqrl t1, (a0)
diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp
index a595526dd24a9a4..fba5413df24a2fa 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -800,6 +800,7 @@ Experimental extensions
     zalrsc              0.2
     zfbfmin             1.0
     zcmop               0.2
+    zalasr              1.0
     ztso                0.1
     zvfbfmin            1.0
     zvfbfwma            1.0

>From 5cd0279a1c1fa803ab1d6e3f9f917cff871c520a Mon Sep 17 00:00:00 2001
From: Brendan Sweeney <turtwig at utexas.edu>
Date: Mon, 18 Dec 2023 11:40:19 -0800
Subject: [PATCH 2/3] Adding isel lowering for Zalasr. Not sure if is matches
 the psABI yet though

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  8 +++
 llvm/lib/Target/RISCV/RISCVISelLowering.h     |  5 +-
 llvm/lib/Target/RISCV/RISCVInstrInfoA.td      | 61 ++++++++++++++++---
 llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td | 34 ++++++++++-
 4 files changed, 94 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 9d49c22fdf21521..dfc7def8f04ba28 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20506,6 +20506,14 @@ unsigned RISCVTargetLowering::getCustomCtpopCost(EVT VT,
   return isCtpopFast(VT) ? 0 : 1;
 }
 
+bool RISCVTargetLowering::shouldInsertFencesForAtomic(const Instruction *I) const {
+  if (Subtarget.hasStdExtZalasr()) {
+    return false;
+  } else {
+    return isa<LoadInst>(I) || isa<StoreInst>(I);
+  }
+}
+
 bool RISCVTargetLowering::fallBackToDAGISel(const Instruction &Inst) const {
 
   // GISel support is in progress or complete for G_ADD, G_SUB, G_AND, G_OR, and
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 8d2fdbb9d40b4a7..9316cfe811ba232 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -689,9 +689,8 @@ class RISCVTargetLowering : public TargetLowering {
 
   bool preferZeroCompareBranch() const override { return true; }
 
-  bool shouldInsertFencesForAtomic(const Instruction *I) const override {
-    return isa<LoadInst>(I) || isa<StoreInst>(I);
-  }
+  bool shouldInsertFencesForAtomic(const Instruction *I) const override;
+
   Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
                                 AtomicOrdering Ord) const override;
   Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
index 36842ceb49bfb82..25bd4ed236b088b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
@@ -105,22 +105,63 @@ defm AMOMAXU_D  : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">,
 // Pseudo-instructions and codegen patterns
 //===----------------------------------------------------------------------===//
 
+// An atomic load operation that does not need either acquire or release
+// semantics.
+class relaxed_load<PatFrags base>
+  : PatFrag<(ops node:$ptr), (base node:$ptr)> {
+  let IsAtomic = 1;
+  let IsAtomicOrderingMonotonic = 1;
+}
+
+// A atomic load operation that actually needs acquire semantics.
+class acquiring_load<PatFrags base>
+  : PatFrag<(ops node:$ptr), (base node:$ptr)> {
+  let IsAtomic = 1;
+  let IsAtomicOrderingAcquire = 1;
+}
+
+// An atomic load operation that needs sequential consistency.
+class seq_cst_load<PatFrags base>
+  : PatFrag<(ops node:$ptr), (base node:$ptr)> {
+  let IsAtomic = 1;
+  let IsAtomicOrderingSequentiallyConsistent = 1;
+}
+
+// An atomic store operation that doesn't actually need to be atomic on RISCV.
+class relaxed_store<PatFrag base>
+  : PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr)> {
+  let IsAtomic = 1;
+  let IsAtomicOrderingMonotonic = 1;
+}
+
+// A store operation that actually needs release semantics.
+class releasing_store<PatFrag base>
+  : PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr)> {
+  let IsAtomic = 1;
+  let IsAtomicOrderingRelease = 1;
+}
+
+// A store operation that actually needs sequential consistency.
+class seq_cst_store<PatFrag base>
+  : PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr)> {
+  let IsAtomic = 1;
+  let IsAtomicOrderingSequentiallyConsistent = 1;
+}
+
 // Atomic load/store are available under both +a and +force-atomics.
-// Fences will be inserted for atomic load/stores according to the logic in
-// RISCVTargetLowering::{emitLeadingFence,emitTrailingFence}.
 let Predicates = [HasAtomicLdSt] in {
-  def : LdPat<atomic_load_8,  LB>;
-  def : LdPat<atomic_load_16, LH>;
-  def : LdPat<atomic_load_32, LW>;
+  def : LdPat<relaxed_load<atomic_load_8>,  LB>;
+  def : LdPat<relaxed_load<atomic_load_16>, LH>;
+  def : LdPat<relaxed_load<atomic_load_32>, LW>;
 
-  def : StPat<atomic_store_8,  SB, GPR, XLenVT>;
-  def : StPat<atomic_store_16, SH, GPR, XLenVT>;
-  def : StPat<atomic_store_32, SW, GPR, XLenVT>;
+  def : StPat<relaxed_store<atomic_store_8>,  SB, GPR, XLenVT>;
+  def : StPat<relaxed_store<atomic_store_16>, SH, GPR, XLenVT>;
+  def : StPat<relaxed_store<atomic_store_32>, SW, GPR, XLenVT>;
 }
 
 let Predicates = [HasAtomicLdSt, IsRV64] in {
-  def : LdPat<atomic_load_64, LD, i64>;
-  def : StPat<atomic_store_64, SD, GPR, i64>;
+  def : LdPat<relaxed_load<atomic_load_64>, LD, i64>;
+  def : StPat<relaxed_store<atomic_store_64>, SD, GPR, i64>;
 }
 
 /// AMOs
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
index cb603bb60306295..8c7cf655eced0ba 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
@@ -63,4 +63,36 @@ defm SD_RL : SRL_r_aq_rl<0b011, "sd">;
 // Pseudo-instructions and codegen patterns
 //===----------------------------------------------------------------------===//
 
-// Future work: Work out mapping with leading/trailing fences, &c
+class PatLAQ<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
+    : Pat<(vt (OpNode (vt GPRMemZeroOffset:$rs1))), (Inst GPRMemZeroOffset:$rs1)>;
+
+class PatSRL<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
+    : Pat<(OpNode (vt GPR:$rs2), (vt GPRMemZeroOffset:$rs1)), (Inst GPR:$rs2, GPRMemZeroOffset:$rs1)>;
+
+let Predicates = [HasStdExtZalasr] in {
+  def : PatLAQ<acquiring_load<atomic_load_8>, LB_AQ_AQ>;
+  def : PatLAQ<seq_cst_load<atomic_load_8>, LB_AQ_AQ_RL>;
+
+  def : PatLAQ<acquiring_load<atomic_load_16>, LH_AQ_AQ>;
+  def : PatLAQ<seq_cst_load<atomic_load_16>, LH_AQ_AQ_RL>;
+
+  def : PatLAQ<acquiring_load<atomic_load_32>, LW_AQ_AQ>;
+  def : PatLAQ<seq_cst_load<atomic_load_32>, LW_AQ_AQ_RL>;
+
+  def : PatSRL<releasing_store<atomic_store_8>, SB_RL_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_8>, SB_RL_AQ_RL>;
+
+  def : PatSRL<releasing_store<atomic_store_16>, SH_RL_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_16>, SH_RL_AQ_RL>;
+
+  def : PatSRL<releasing_store<atomic_store_32>, SW_RL_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_32>, SW_RL_AQ_RL>;
+} // Predicates HasStdExtZalasr
+
+let Predicates = [HasStdExtZalasr, IsRV64] in {
+  def : PatLAQ<acquiring_load<atomic_load_64>, LD_AQ_AQ>;
+  def : PatLAQ<seq_cst_load<atomic_load_64>, LD_AQ_AQ_RL>;
+
+  def : PatSRL<releasing_store<atomic_store_64>, SD_RL_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_64>, SD_RL_AQ_RL>;
+} // Predicates HasStdExtZalasr, IsRV64

>From 25115f968e85bd42a49e4c1d8a0e7a1be99c11a0 Mon Sep 17 00:00:00 2001
From: Brendan Sweeney <turtwig at utexas.edu>
Date: Thu, 25 Jan 2024 16:43:37 -0600
Subject: [PATCH 3/3] Making Zalasr lowering match the psABI (aka lb.aqrl and
 sb.aqrl are no longer used in the lowering)

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  3 ++-
 llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td | 16 ++++++++--------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index dfc7def8f04ba28..9ebe8e7a917d613 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20506,7 +20506,8 @@ unsigned RISCVTargetLowering::getCustomCtpopCost(EVT VT,
   return isCtpopFast(VT) ? 0 : 1;
 }
 
-bool RISCVTargetLowering::shouldInsertFencesForAtomic(const Instruction *I) const {
+bool RISCVTargetLowering::shouldInsertFencesForAtomic(
+    const Instruction *I) const {
   if (Subtarget.hasStdExtZalasr()) {
     return false;
   } else {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
index 8c7cf655eced0ba..b0acdf3d4a4b161 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
@@ -71,28 +71,28 @@ class PatSRL<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
 
 let Predicates = [HasStdExtZalasr] in {
   def : PatLAQ<acquiring_load<atomic_load_8>, LB_AQ_AQ>;
-  def : PatLAQ<seq_cst_load<atomic_load_8>, LB_AQ_AQ_RL>;
+  def : PatLAQ<seq_cst_load<atomic_load_8>, LB_AQ_AQ>; // these use lb.aq instead of lb.aqrl to match the psABI
 
   def : PatLAQ<acquiring_load<atomic_load_16>, LH_AQ_AQ>;
-  def : PatLAQ<seq_cst_load<atomic_load_16>, LH_AQ_AQ_RL>;
+  def : PatLAQ<seq_cst_load<atomic_load_16>, LH_AQ_AQ>;
 
   def : PatLAQ<acquiring_load<atomic_load_32>, LW_AQ_AQ>;
-  def : PatLAQ<seq_cst_load<atomic_load_32>, LW_AQ_AQ_RL>;
+  def : PatLAQ<seq_cst_load<atomic_load_32>, LW_AQ_AQ>;
 
   def : PatSRL<releasing_store<atomic_store_8>, SB_RL_RL>;
-  def : PatSRL<seq_cst_store<atomic_store_8>, SB_RL_AQ_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_8>, SB_RL_RL>; // these use sb.rl instead of sb.aqrl to match the psABI
 
   def : PatSRL<releasing_store<atomic_store_16>, SH_RL_RL>;
-  def : PatSRL<seq_cst_store<atomic_store_16>, SH_RL_AQ_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_16>, SH_RL_RL>;
 
   def : PatSRL<releasing_store<atomic_store_32>, SW_RL_RL>;
-  def : PatSRL<seq_cst_store<atomic_store_32>, SW_RL_AQ_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_32>, SW_RL_RL>;
 } // Predicates HasStdExtZalasr
 
 let Predicates = [HasStdExtZalasr, IsRV64] in {
   def : PatLAQ<acquiring_load<atomic_load_64>, LD_AQ_AQ>;
-  def : PatLAQ<seq_cst_load<atomic_load_64>, LD_AQ_AQ_RL>;
+  def : PatLAQ<seq_cst_load<atomic_load_64>, LD_AQ_AQ>;
 
   def : PatSRL<releasing_store<atomic_store_64>, SD_RL_RL>;
-  def : PatSRL<seq_cst_store<atomic_store_64>, SD_RL_AQ_RL>;
+  def : PatSRL<seq_cst_store<atomic_store_64>, SD_RL_RL>;
 } // Predicates HasStdExtZalasr, IsRV64



More information about the llvm-commits mailing list