[clang] [llvm] [RISCV][MC] Support experimental Zilx extension (PR #209419)
Pengcheng Wang via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 14 03:01:43 PDT 2026
https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/209419
>From b53382e270d8365c7b5222c2b4dd3220c44a697f Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Tue, 14 Jul 2026 17:50:28 +0800
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
---
.../Driver/print-supported-extensions-riscv.c | 1 +
.../test/Preprocessor/riscv-target-features.c | 1 +
llvm/docs/RISCVUsage.rst | 3 +
llvm/docs/ReleaseNotes.md | 1 +
llvm/lib/Target/RISCV/RISCVFeatures.td | 7 ++
llvm/lib/Target/RISCV/RISCVInstrInfo.td | 1 +
llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td | 73 ++++++++++++++++
llvm/test/CodeGen/RISCV/attributes.ll | 4 +
llvm/test/CodeGen/RISCV/features-info.ll | 1 +
llvm/test/MC/RISCV/zilx-invalid.s | 16 ++++
llvm/test/MC/RISCV/zilx-valid-rv32.s | 47 ++++++++++
llvm/test/MC/RISCV/zilx-valid-rv64.s | 87 +++++++++++++++++++
.../TargetParser/RISCVISAInfoTest.cpp | 1 +
13 files changed, 243 insertions(+)
create mode 100644 llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
create mode 100644 llvm/test/MC/RISCV/zilx-invalid.s
create mode 100644 llvm/test/MC/RISCV/zilx-valid-rv32.s
create mode 100644 llvm/test/MC/RISCV/zilx-valid-rv64.s
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index a9af276367817..2ac69230a3601 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -249,6 +249,7 @@
// CHECK-NEXT: zibi 0.1 'Zibi' (Branch with Immediate)
// CHECK-NEXT: zicfilp 1.0 'Zicfilp' (Landing pad)
// CHECK-NEXT: zicfiss 1.0 'Zicfiss' (Shadow stack)
+// CHECK-NEXT: zilx 0.1 'Zilx' (Index Load for Integer)
// CHECK-NEXT: zvabd 0.7 'Zvabd' (Vector Absolute Difference)
// CHECK-NEXT: zvbc32e 0.7 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements)
// CHECK-NEXT: zvdot4a8i 0.1 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers)
diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 28031814da16a..bf9689d7462aa 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -129,6 +129,7 @@
// CHECK-NOT: __riscv_zihintpause {{.*$}}
// CHECK-NOT: __riscv_zihpm {{.*$}}
// CHECK-NOT: __riscv_zilsd {{.*$}}
+// CHECK-NOT: __riscv_zilx {{.*$}}
// CHECK-NOT: __riscv_zimop {{.*$}}
// CHECK-NOT: __riscv_zk {{.*$}}
// CHECK-NOT: __riscv_zkn {{.*$}}
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 72428398fc465..58832def18310 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -385,6 +385,9 @@ The primary goal of experimental support is to assist in the process of ratifica
``experimental-zvqwbdota8i``, ``experimental-zvqwbdota16i``, ``experimental-zvfqwbdota8f``, ``experimental-zvfwbdota16bf``, ``experimental-zvfbdota32f``
LLVM implements the `0.2 draft specification <https://github.com/aswaterman/riscv-misc/blob/main/isa/ldot-bdot/ldot-bdot.adoc>`__.
+``experimental-zilx``
+ LLVM implements the `0.1 draft specification <https://lists.riscv.org/g/tech-arch-review/message/453>`__.
+
To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
Vendor Extensions
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index e4c2149d9c18a..7a10d012138a6 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -282,6 +282,7 @@ Makes programs 10x faster by doing Special New Thing.
* Adds experimental assembler support for dot-product extensions(Zvqwdota8i, Zvqwdota16i, Zvfwdota16bf and Zvfqwdota8f).
* `-mtune=generic` now uses the scheduling model from SpacemiT X60 instead of an empty scheduling model.
* The Xqcilo pseudos now emit sequences that can be relaxed.
+* Adds experimental assembler support for the 'Zilx` (Index Load For Integer) extension.
### Changes to the WebAssembly Backend
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 03d28b8448ba4..99d641a762c1f 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -204,6 +204,13 @@ def FeatureZilsdWordAlign
: SubtargetFeature<"zilsd-word-align", "AllowZilsdWordAlign", "true",
"Allow 4-byte alignment for Zilsd LD/SD instructions">;
+def FeatureStdExtZilx
+ : RISCVExperimentalExtension<0, 1, "Index Load for Integer">;
+def HasStdExtZilx
+ : Predicate<"Subtarget->hasStdExtZilx()">,
+ AssemblerPredicate<(all_of FeatureStdExtZilx),
+ "'Zilx' (Index Load for Integer)">;
+
// Multiply Extensions
def FeatureStdExtZmmul
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index e10ee7389db0e..5cef2f042bd33 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2374,6 +2374,7 @@ include "RISCVInstrInfoZicbo.td"
include "RISCVInstrInfoZicond.td"
include "RISCVInstrInfoZilsd.td"
include "RISCVInstrInfoZibi.td"
+include "RISCVInstrInfoZilx.td"
// Scalar FP
include "RISCVInstrInfoF.td"
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
new file mode 100644
index 0000000000000..2c43e4e30eb31
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
@@ -0,0 +1,73 @@
+//===-- RISCVInstrInfoZilx.td - 'Zilx' 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 for 'Zilx' (Index Load for
+/// Integer).
+///
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class IndexLoadCommon<bits<3> type, bits<2> width, bit isUnsigned,
+ dag outs, dag ins,
+ string opcodestr, string format>
+ : RVInstI<0b111, OPC_LOAD, outs, ins, opcodestr, format> {
+ let Inst{31-30} = width;
+ let Inst{29} = isUnsigned;
+ let Inst{28} = 0b0;
+ let Inst{27-25} = type;
+}
+
+class UnscaledIndexLoad<bits<3> type, bits<2> width, bit isUnsigned, string opcodestr>
+ : IndexLoadCommon<type, width, isUnsigned, (outs GPR:$rd),
+ (ins GPRMemZeroOffset:$rs1, GPR:$rs2),
+ opcodestr, "$rd, $rs1, $rs2"> {
+ bits<5> rs2;
+
+ let Inst{24-20} = rs2;
+}
+
+class ScaledIndexLoad<bits<3> type, bits<2> width, bit isUnsigned, string opcodestr>
+ : IndexLoadCommon<type, width, isUnsigned, (outs GPR:$rd),
+ (ins GPRMemZeroOffset:$rs1, GPR:$rs2),
+ opcodestr, "$rd, $rs1, $rs2"> {
+ bits<5> rs2;
+
+ let Inst{24-20} = rs2;
+}
+
+let Predicates = [HasStdExtZilx] in {
+def LXB : UnscaledIndexLoad<0b010, 0b00, 0, "lxb">, Sched<[WriteLDB, ReadMemBase, ReadMemBase]>;
+def LXB_UW : UnscaledIndexLoad<0b011, 0b00, 0, "lxb.uw">, Sched<[WriteLDB, ReadMemBase, ReadMemBase]>;
+def LXBU : UnscaledIndexLoad<0b010, 0b00, 1, "lxbu">, Sched<[WriteLDB, ReadMemBase, ReadMemBase]>;
+def LXBU_UW : UnscaledIndexLoad<0b011, 0b00, 1, "lxbu.uw">, Sched<[WriteLDB, ReadMemBase, ReadMemBase]>;
+def LXH : UnscaledIndexLoad<0b010, 0b01, 0, "lxh">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXH_UW : UnscaledIndexLoad<0b011, 0b01, 0, "lxh.uw">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXHU : UnscaledIndexLoad<0b010, 0b01, 1, "lxhu">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXHU_UW : UnscaledIndexLoad<0b011, 0b01, 1, "lxhu.uw">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXW : UnscaledIndexLoad<0b010, 0b10, 0, "lxw">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+def LXW_UW : UnscaledIndexLoad<0b011, 0b10, 0, "lxw.uw">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+
+def LXH_S : ScaledIndexLoad<0b100, 0b01, 0, "lxh.s">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXH_S_UW : ScaledIndexLoad<0b101, 0b01, 0, "lxh.s.uw">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXHU_S : ScaledIndexLoad<0b100, 0b01, 1, "lxhu.s">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXHU_S_UW : ScaledIndexLoad<0b101, 0b01, 1, "lxhu.s.uw">, Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+def LXW_S : ScaledIndexLoad<0b100, 0b10, 0, "lxw.s">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+def LXW_S_UW : ScaledIndexLoad<0b101, 0b10, 0, "lxw.s.uw">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+} // Predicates = [HasStdExtZilx]
+
+let Predicates = [HasStdExtZilx, IsRV64] in {
+def LXWU : UnscaledIndexLoad<0b010, 0b10, 1, "lxwu">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+def LXWU_UW : UnscaledIndexLoad<0b011, 0b10, 1, "lxwu.uw">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+def LXD : UnscaledIndexLoad<0b010, 0b11, 0, "lxd">, Sched<[WriteLDD, ReadMemBase, ReadMemBase]>;
+def LXD_UW : UnscaledIndexLoad<0b011, 0b11, 0, "lxd.uw">, Sched<[WriteLDD, ReadMemBase, ReadMemBase]>;
+
+def LXWU_S : ScaledIndexLoad<0b100, 0b10, 1, "lxwu.s">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+def LXWU_S_UW : ScaledIndexLoad<0b101, 0b10, 1, "lxwu.s.uw">, Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+def LXD_S : ScaledIndexLoad<0b100, 0b11, 0, "lxd.s">, Sched<[WriteLDD, ReadMemBase, ReadMemBase]>;
+def LXD_S_UW : ScaledIndexLoad<0b101, 0b11, 0, "lxd.s.uw">, Sched<[WriteLDD, ReadMemBase, ReadMemBase]>;
+} // Predicates = [HasStdExtZilsx, IsRV64]
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 26ffd8bb4ec89..566786526dc7c 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -152,6 +152,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+ssctr %s -o - | FileCheck --check-prefix=RV32SSCTR %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV32P %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zibi %s -o - | FileCheck --check-prefix=RV32ZIBI %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zilx %s -o - | FileCheck --check-prefix=RV32ZILX %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvqwbdota8i %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVQWBDOTA8I %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvqwbdota16i %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVQWBDOTA16I %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfwbdota16bf %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFWBDOTA16BF %s
@@ -320,6 +321,7 @@
; RUN: llc -mtriple=riscv64 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV64P %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-y %s -o - | FileCheck --check-prefix=RV64Y %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zibi %s -o - | FileCheck --check-prefix=RV64ZIBI %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zilx %s -o - | FileCheck --check-prefix=RV64ZILX %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvqwbdota8i %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVQWBDOTA8I %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvqwbdota16i %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVQWBDOTA16I %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfwbdota16bf %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFWBDOTA16BF %s
@@ -457,6 +459,7 @@
; RV32ZVABD: .attribute 5, "rv32i2p1_zicsr2p0_zvabd0p7_zve32x1p0_zvl32b1p0"
; RV32ZICOND: .attribute 5, "rv32i2p1_zicond1p0"
; RV32ZILSD: .attribute 5, "rv32i2p1_zilsd1p0"
+; RV32ZILX: .attribute 5, "rv32i2p1_zilx0p1"
; RV32ZIMOP: .attribute 5, "rv32i2p1_zimop1p0"
; RV32ZCLSD: .attribute 5, "rv32i2p1_c2p0_zilsd1p0_zca1p0_zclsd1p0"
; RV32ZCMOP: .attribute 5, "rv32i2p1_c2p0_zca1p0_zcmop1p0"
@@ -621,6 +624,7 @@
; RV64ZVFH: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfhmin1p0_zve32f1p0_zve32x1p0_zvfh1p0_zvfhmin1p0_zvl32b1p0"
; RV64ZVABD: .attribute 5, "rv64i2p1_zicsr2p0_zvabd0p7_zve32x1p0_zvl32b1p0"
; RV64ZICOND: .attribute 5, "rv64i2p1_zicond1p0"
+; RV64ZILX: .attribute 5, "rv64i2p1_zilx0p1"
; RV64ZIMOP: .attribute 5, "rv64i2p1_zimop1p0"
; RV64ZCMOP: .attribute 5, "rv64i2p1_c2p0_zca1p0_zcmop1p0"
; RV64SMAIA: .attribute 5, "rv64i2p1_smaia1p0"
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 142e6b2694937..bb822a4379068 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -33,6 +33,7 @@
; CHECK-NEXT: experimental-zibi - 'Zibi' (Branch with Immediate).
; CHECK-NEXT: experimental-zicfilp - 'Zicfilp' (Landing pad).
; CHECK-NEXT: experimental-zicfiss - 'Zicfiss' (Shadow stack).
+; CHECK-NEXT: experimental-zilx - 'Zilx' (Index Load for Integer).
; CHECK-NEXT: experimental-zvabd - 'Zvabd' (Vector Absolute Difference).
; CHECK-NEXT: experimental-zvbc32e - 'Zvbc32e' (Vector Carryless Multiplication with 32-bits elements).
; CHECK-NEXT: experimental-zvdot4a8i - 'Zvdot4a8i' (Vector 4-element Dot Product of packed 8-bit Integers).
diff --git a/llvm/test/MC/RISCV/zilx-invalid.s b/llvm/test/MC/RISCV/zilx-invalid.s
new file mode 100644
index 0000000000000..d5415a0a6e288
--- /dev/null
+++ b/llvm/test/MC/RISCV/zilx-invalid.s
@@ -0,0 +1,16 @@
+# RUN: not llvm-mc -triple=riscv32 --mattr=+experimental-zilx %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-zilx %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+
+# CHECK-ERROR: :[[@LINE+1]]:9: error: expected '(' or optional integer offset
+lxh a0, a1, a2
+
+# CHECK-ERROR: :[[@LINE+1]]:12: error: expected '(' or optional integer offset
+lxh.uw a0, a1, a2
+
+# CHECK-ERROR: :[[@LINE+1]]:11: error: expected '(' or optional integer offset
+lxh.s a0, a1, a2
+
+# CHECK-ERROR: :[[@LINE+1]]:14: error: expected '(' or optional integer offset
+lxh.s.uw a0, a1, a2
diff --git a/llvm/test/MC/RISCV/zilx-valid-rv32.s b/llvm/test/MC/RISCV/zilx-valid-rv32.s
new file mode 100644
index 0000000000000..ee2bdbd35b6d1
--- /dev/null
+++ b/llvm/test/MC/RISCV/zilx-valid-rv32.s
@@ -0,0 +1,47 @@
+# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+experimental-zilx %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv32 -show-encoding %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+experimental-zilx %s \
+# RUN: | llvm-objdump -d --mattr=+experimental-zilx --no-print-imm-hex - \
+# RUN: | FileCheck %s --check-prefix=CHECK-INST
+
+lxb a0, (a1), a2
+# CHECK-INST: lxb a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x04]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxbu a0, (a1), a2
+# CHECK-INST: lxbu a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x24]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxh a0, (a1), a2
+# CHECK-INST: lxh a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x44]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxhu a0, (a1), a2
+# CHECK-INST: lxhu a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x64]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxw a0, (a1), a2
+# CHECK-INST: lxw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x84]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxh.s a0, (a1), a2
+# CHECK-INST: lxh.s a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x48]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxhu.s a0, (a1), a2
+# CHECK-INST: lxhu.s a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x68]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxw.s a0, (a1), a2
+# CHECK-INST: lxw.s a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x88]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
diff --git a/llvm/test/MC/RISCV/zilx-valid-rv64.s b/llvm/test/MC/RISCV/zilx-valid-rv64.s
new file mode 100644
index 0000000000000..5b51857db7883
--- /dev/null
+++ b/llvm/test/MC/RISCV/zilx-valid-rv64.s
@@ -0,0 +1,87 @@
+# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+experimental-zilx %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+experimental-zilx %s \
+# RUN: | llvm-objdump -d --mattr=+experimental-zilx --no-print-imm-hex - \
+# RUN: | FileCheck %s --check-prefix=CHECK-INST
+
+lxwu a0, (a1), a2
+# CHECK-INST: lxwu a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xa4]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxd a0, (a1), a2
+# CHECK-INST: lxd a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xc4]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxb.uw a0, (a1), a2
+# CHECK-INST: lxb.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x06]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxbu.uw a0, (a1), a2
+# CHECK-INST: lxbu.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x26]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxh.uw a0, (a1), a2
+# CHECK-INST: lxh.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x46]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxhu.uw a0, (a1), a2
+# CHECK-INST: lxhu.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x66]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxw.uw a0, (a1), a2
+# CHECK-INST: lxw.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x86]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxwu.uw a0, (a1), a2
+# CHECK-INST: lxwu.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xa6]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxd.uw a0, (a1), a2
+# CHECK-INST: lxd.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xc6]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxwu.s a0, (a1), a2
+# CHECK-INST: lxwu.s a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xa8]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxd.s a0, (a1), a2
+# CHECK-INST: lxd.s a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xc8]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxh.s.uw a0, (a1), a2
+# CHECK-INST: lxh.s.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x4a]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxhu.s.uw a0, (a1), a2
+# CHECK-INST: lxhu.s.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x6a]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxw.s.uw a0, (a1), a2
+# CHECK-INST: lxw.s.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0x8a]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxwu.s.uw a0, (a1), a2
+# CHECK-INST: lxwu.s.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xaa]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
+
+lxd.s.uw a0, (a1), a2
+# CHECK-INST: lxd.s.uw a0, (a1), a2
+# CHECK-ENCODING: [0x03,0xf5,0xc5,0xca]
+# CHECK-ERROR: instruction requires the following: 'Zilx' (Index Load for Integer){{$}}
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index cdc2fcea37fcb..449f27fad3f54 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1618,6 +1618,7 @@ Experimental extensions
zibi 0.1
zicfilp 1.0 This is a long dummy description
zicfiss 1.0
+ zilx 0.1
zvabd 0.7
zvbc32e 0.7
zvdot4a8i 0.1
>From 884a1e13ff28551f49394cd3f1b23fec7ce6c6d8 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Tue, 14 Jul 2026 18:01:30 +0800
Subject: [PATCH 2/2] Update spec URL
Created using spr 1.3.6-beta.1
---
llvm/docs/RISCVUsage.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 58832def18310..3fc5db5131803 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -386,7 +386,7 @@ The primary goal of experimental support is to assist in the process of ratifica
LLVM implements the `0.2 draft specification <https://github.com/aswaterman/riscv-misc/blob/main/isa/ldot-bdot/ldot-bdot.adoc>`__.
``experimental-zilx``
- LLVM implements the `0.1 draft specification <https://lists.riscv.org/g/tech-arch-review/message/453>`__.
+ LLVM implements the `0.1 draft specification <https://github.com/riscv/riscv-zilx>`__.
To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
More information about the cfe-commits
mailing list