https://github.com/mehnadnerd updated https://github.com/llvm/llvm-project/pull/69685
>From 56081a5bfe14605a692c3b49dd5c37625673aadf Mon Sep 17 00:00:00 2001 From: brs <turt...@utexas.edu> Date: Thu, 19 Oct 2023 17:16:45 -0500 Subject: [PATCH 1/2] [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 6fc921a8c6ee15..6f7c8224d1283e 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -116,6 +116,7 @@ // CHECK-NOT: __riscv_smaia {{.*$}} // CHECK-NOT: __riscv_ssaia {{.*$}} // CHECK-NOT: __riscv_zacas {{.*$}} +// CHECK-NOT: __riscv_zalasr {{.*$}} // CHECK-NOT: __riscv_zfa {{.*$}} // CHECK-NOT: __riscv_zfbfmin {{.*$}} // CHECK-NOT: __riscv_zicfilp {{.*$}} @@ -1039,6 +1040,14 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s // CHECK-ZACAS-EXT: __riscv_zacas 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 -x c -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 65dd0d83448ed1..e7d32379724c1f 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -193,6 +193,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 `0.8.0 draft specification <https://github.com/riscv/riscv-bfloat16/releases/tag/20230629>`_. diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 6322748430063c..5a83ba4dcf54e8 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -171,6 +171,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = { // NOTE: This table should be sorted alphabetically by extension name. static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { {"zacas", RISCVExtensionVersion{1, 0}}, + {"zalasr", RISCVExtensionVersion{1, 0}}, {"zfbfmin", RISCVExtensionVersion{0, 8}}, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index c5d88ca306969f..0165310714462a 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -715,6 +715,13 @@ def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">, AssemblerPredicate<(all_of FeatureStdExtZacas), "'Zacas' (Atomic Compare-And-Swap Instructions)">; +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 edc08187d8f775..8dc85dd06223f3 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -2095,6 +2095,7 @@ include "RISCVInstrInfoM.td" // Atomic include "RISCVInstrInfoA.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 00000000000000..cb603bb6030629 --- /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 030ae06af6d282..05b165f60bc58a 100644 --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -90,6 +90,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFBFWMA %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV32ZACAS %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 @@ -180,6 +181,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFBFWMA %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %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 @@ -272,6 +274,7 @@ ; RV32ZVFBFWMA: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfbfmin0p8_zve32f1p0_zve32x1p0_zvfbfmin0p8_zvfbfwma0p8_zvl32b1p0" ; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0" ; RV32ZICFILP: .attribute 5, "rv32i2p1_zicfilp0p2" +; RV32ZALASR: .attribute 5, "rv32i2p1_zalasr1p0" ; RV64M: .attribute 5, "rv64i2p1_m2p0" ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0" @@ -361,6 +364,7 @@ ; RV64ZVFBFWMA: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfbfmin0p8_zve32f1p0_zve32x1p0_zvfbfmin0p8_zvfbfwma0p8_zvl32b1p0" ; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0" ; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p2" +; 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 aa919f266592f4..34f9ed7dcf4d14 100644 --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -288,6 +288,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 00000000000000..3731c85cbc077f --- /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 00000000000000..fb85fbc00dfea2 --- /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 00000000000000..032c0c00882cbf --- /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 00000000000000..9e623ccaaaf887 --- /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 549964eed55518..f7412f65ed33da 100644 --- a/llvm/unittests/Support/RISCVISAInfoTest.cpp +++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp @@ -739,6 +739,7 @@ Experimental extensions zicfilp 0.2 This is a long dummy description zicond 1.0 zacas 1.0 + zalasr 1.0 zfbfmin 0.8 ztso 0.1 zvbb 1.0 >From 89b78a0af5547fc4c0c85368698c1bd2b0151993 Mon Sep 17 00:00:00 2001 From: Brendan Sweeney <turt...@utexas.edu> Date: Mon, 18 Dec 2023 11:40:19 -0800 Subject: [PATCH 2/2] 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 18c6ca5348b621..c7f192e889561f 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -19764,6 +19764,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 { // At the moment, the only scalable instruction GISel knows how to lower is // ret with scalable argument. diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 486efeb8339ab0..8487cac53f7cf5 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -615,9 +615,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 c8301fcc6b9388..1a4c09e97c22c6 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td @@ -109,22 +109,63 @@ defm AMOCAS_Q : AMO_rr_aq_rl<0b00101, 0b100, "amocas.q">; // 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 IsAtomicOrderingReleaseOrStronger = 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 cb603bb6030629..8c7cf655eced0b 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits