[llvm-branch-commits] [llvm] [RISCV] Support CodeGen of Zilx extension (PR #209420)

Pengcheng Wang via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jul 29 23:47:40 PDT 2026


https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/209420

>From bf5ad3b324ff511ecc67ecf14c25cddabf9c7aa1 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Tue, 14 Jul 2026 17:56:49 +0800
Subject: [PATCH 01/10] clang-format

Created using spr 1.3.6-beta.1
---
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 9208762e8d1fe..0e69533f56a50 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3736,8 +3736,8 @@ static bool isRegRegScaleLoadOrStore(SDNode *User, SDValue Add,
     return false;
   EVT VT = cast<MemSDNode>(User)->getMemoryVT();
   if (!(VT.isScalarInteger() &&
-        (Subtarget.hasStdExtZilx() ||
-         Subtarget.hasVendorXTHeadMemIdx() || Subtarget.hasVendorXqcisls())) &&
+        (Subtarget.hasStdExtZilx() || Subtarget.hasVendorXTHeadMemIdx() ||
+         Subtarget.hasVendorXqcisls())) &&
       !((VT == MVT::f32 || VT == MVT::f64) &&
         Subtarget.hasVendorXTHeadFMemIdx()))
     return false;

>From ddc4fe1cd521bff676fcf361ab67acc72ad1671f Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Wed, 15 Jul 2026 14:49:45 +0800
Subject: [PATCH 02/10] Increase Complexity

Created using spr 1.3.6-beta.1
---
 llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
index c7247efed0f4c..7c12cd63f99d0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
@@ -86,10 +86,11 @@ def LXD_S_UW  : IndexedLoad<0b101, 0b11, 0, "lxd.s.uw">,
 } // Predicates = [HasStdExtZilx, IsRV64]
 
 class AddrRegReg<int N>
-    : ComplexPattern<iPTR, 2, "SelectAddrRegRegFixedScale<"#N#">">;
+    : ComplexPattern<iPTR, 2, "SelectAddrRegRegFixedScale<"#N#">",
+                     [], [], !add(10, N)>;
 class AddrRegZextReg<int N>
     : ComplexPattern<i64, 2, "SelectAddrRegZextRegFixedScale<"#N#", 32>",
-                     [], [], 10>;
+                     [], [], !add(20, N)>;
 
 def AddrRegReg0 : AddrRegReg<0>;
 def AddrRegReg1 : AddrRegReg<1>;

>From 210e1a40980749a2f028c26f6fa863391f1e62be Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Wed, 15 Jul 2026 14:58:14 +0800
Subject: [PATCH 03/10] Add more tests

Created using spr 1.3.6-beta.1
---
 llvm/test/CodeGen/RISCV/zilx.ll | 279 ++++++++++++++++++++++++++++++++
 1 file changed, 279 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/zilx.ll b/llvm/test/CodeGen/RISCV/zilx.ll
index 3a27d801230a7..5ec14ca429a95 100644
--- a/llvm/test/CodeGen/RISCV/zilx.ll
+++ b/llvm/test/CodeGen/RISCV/zilx.ll
@@ -968,3 +968,282 @@ define i64 @lxd_s_uw(ptr %a, i32 %b) {
   %3 = load i64, ptr %2, align 8
   ret i64 %3
 }
+
+;------------------------------------------------------------------------------
+; Load with a shift amount that doesn't match the access size
+;
+; The scaled forms require the index shift amount to match log2 of the access
+; size. When the shift is smaller or larger than the access size the scaled
+; forms can't be used: the shift is materialized separately, but the base+index
+; add can still fold into the unscaled index load.
+;------------------------------------------------------------------------------
+
+; i8 access with the index scaled by 2 (larger than the access size).
+define zeroext i8 @lxbu_shl_too_large(ptr %a, iXLen %b) {
+; RV32-LABEL: lxbu_shl_too_large:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 2
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lbu a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxbu_shl_too_large:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    slli a1, a1, 2
+; RV32-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxbu_shl_too_large:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 2
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lbu a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxbu_shl_too_large:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 2
+; RV64-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i32, ptr %a, iXLen %b
+  %2 = load i8, ptr %1, align 1
+  ret i8 %2
+}
+
+; i16 access with the index scaled by 2 (larger than the access size).
+define signext i16 @lxh_s_shl_too_large(ptr %a, iXLen %b) {
+; RV32-LABEL: lxh_s_shl_too_large:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 2
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lh a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxh_s_shl_too_large:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    slli a1, a1, 2
+; RV32-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxh_s_shl_too_large:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 2
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lh a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxh_s_shl_too_large:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 2
+; RV64-ZILX-NEXT:    lxh a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i32, ptr %a, iXLen %b
+  %2 = load i16, ptr %1, align 2
+  ret i16 %2
+}
+
+; i32 access with the index scaled by 1 (smaller than the access size).
+define i32 @lxw_s_shl_too_small(ptr %a, iXLen %b) {
+; RV32-LABEL: lxw_s_shl_too_small:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 1
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lw a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxw_s_shl_too_small:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    slli a1, a1, 1
+; RV32-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxw_s_shl_too_small:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 1
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lw a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxw_s_shl_too_small:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 1
+; RV64-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i16, ptr %a, iXLen %b
+  %2 = load i32, ptr %1, align 4
+  ret i32 %2
+}
+
+; i32 access with the index scaled by 3 (larger than the access size).
+define i32 @lxw_s_shl_too_large(ptr %a, iXLen %b) {
+; RV32-LABEL: lxw_s_shl_too_large:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 3
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lw a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxw_s_shl_too_large:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    slli a1, a1, 3
+; RV32-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxw_s_shl_too_large:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 3
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lw a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxw_s_shl_too_large:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 3
+; RV64-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i64, ptr %a, iXLen %b
+  %2 = load i32, ptr %1, align 4
+  ret i32 %2
+}
+
+; i64 access with the index scaled by 2 (smaller than the access size).
+define i64 @lxd_s_shl_too_small(ptr %a, iXLen %b) {
+; RV32-LABEL: lxd_s_shl_too_small:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 2
+; RV32-NEXT:    add a1, a0, a1
+; RV32-NEXT:    lw a0, 0(a1)
+; RV32-NEXT:    lw a1, 4(a1)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxd_s_shl_too_small:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    addi a2, a0, 4
+; RV32-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV32-ZILX-NEXT:    lxw.s a1, (a2), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxd_s_shl_too_small:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 2
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    ld a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxd_s_shl_too_small:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 2
+; RV64-ZILX-NEXT:    lxd a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i32, ptr %a, iXLen %b
+  %2 = load i64, ptr %1, align 8
+  ret i64 %2
+}
+
+; i16 access with the zero-extended index scaled by 2 (larger than the access
+; size).
+define signext i16 @lxh_s_uw_shl_too_large(ptr %a, i32 %b) {
+; RV32-LABEL: lxh_s_uw_shl_too_large:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 2
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lh a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxh_s_uw_shl_too_large:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    slli a1, a1, 2
+; RV32-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxh_s_uw_shl_too_large:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 30
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lh a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxh_s_uw_shl_too_large:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 32
+; RV64-ZILX-NEXT:    srli a1, a1, 30
+; RV64-ZILX-NEXT:    lxh a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i32, ptr %a, i64 %1
+  %3 = load i16, ptr %2, align 2
+  ret i16 %3
+}
+
+; i32 access with the zero-extended index scaled by 1 (smaller than the access
+; size).
+define i32 @lxw_s_uw_shl_too_small(ptr %a, i32 %b) {
+; RV32-LABEL: lxw_s_uw_shl_too_small:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 1
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lw a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxw_s_uw_shl_too_small:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    slli a1, a1, 1
+; RV32-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxw_s_uw_shl_too_small:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 31
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lw a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxw_s_uw_shl_too_small:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 32
+; RV64-ZILX-NEXT:    srli a1, a1, 31
+; RV64-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i16, ptr %a, i64 %1
+  %3 = load i32, ptr %2, align 4
+  ret i32 %3
+}
+
+; i32 access with the zero-extended index scaled by 3 (larger than the access
+; size).
+define i32 @lxw_s_uw_shl_too_large(ptr %a, i32 %b) {
+; RV32-LABEL: lxw_s_uw_shl_too_large:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a1, a1, 3
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lw a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxw_s_uw_shl_too_large:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    slli a1, a1, 3
+; RV32-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxw_s_uw_shl_too_large:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 29
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lw a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxw_s_uw_shl_too_large:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    slli a1, a1, 32
+; RV64-ZILX-NEXT:    srli a1, a1, 29
+; RV64-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i64, ptr %a, i64 %1
+  %3 = load i32, ptr %2, align 4
+  ret i32 %3
+}

>From f092d03628360072a4000f1ab5e561d6e5697c3b Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Thu, 16 Jul 2026 11:51:00 +0800
Subject: [PATCH 04/10] Add comments and change the calculation of complexities

Created using spr 1.3.6-beta.1
---
 llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
index 900971d282b1b..eb9f124dcc5cd 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
@@ -85,12 +85,25 @@ def LXD_S_UW  : IndexedLoad<0b101, 0b11, 0, "lxd.s.uw">,
                 Sched<[WriteLDD, ReadMemBase, ReadMemBase]>;
 } // Predicates = [HasStdExtZilx, IsRV64]
 
+// The complexities below are chosen to give the indexed loads a strict
+// priority over the plain reg+imm loads and to encode which form is the more
+// specific match. Without an explicit complexity these patterns tie with the
+// base L{B,H,W,D}[U] patterns (which also match a "reg + reg" address as
+// base+0) and, being listed later, would never be selected. The required
+// ordering is:
+//   base L*  <  scale-0 (unscaled) Zilx  <  scaled Zilx
+// For a given load only the scale-0 form (which leaves the shift as a separate
+// slli) and the exactly-matching scaled form can compete, so a scaled load
+// only needs to outrank its own unscaled form; distinct non-zero scales never
+// compete for the same node.
 class AddrRegReg<int N>
     : ComplexPattern<iPTR, 2, "SelectAddrRegRegFixedScale<"#N#">",
-                     [], [], !add(10, N)>;
+                     [], [], !if(!eq(N, 0), 10, 11)>;
+// The zero-extended-index forms additionally fold the zext, so they are the
+// most specific match and must outrank the plain AddrRegReg forms above.
 class AddrRegZextReg<int N>
     : ComplexPattern<i64, 2, "SelectAddrRegZextRegFixedScale<"#N#", 32>",
-                     [], [], !add(20, N)>;
+                     [], [], !if(!eq(N, 0), 20, 21)>;
 
 def AddrRegReg0 : AddrRegReg<0>;
 def AddrRegReg1 : AddrRegReg<1>;

>From d0047ee92da6a64e256f9864ab293ecc9e99cea2 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Fri, 17 Jul 2026 11:21:44 +0800
Subject: [PATCH 05/10] Add RUNs with zba and zba+zilx

Created using spr 1.3.6-beta.1
---
 llvm/test/CodeGen/RISCV/zilx.ll | 912 ++++++++++++++++++++++++++++++++
 1 file changed, 912 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/zilx.ll b/llvm/test/CodeGen/RISCV/zilx.ll
index 5ec14ca429a95..0f10230077388 100644
--- a/llvm/test/CodeGen/RISCV/zilx.ll
+++ b/llvm/test/CodeGen/RISCV/zilx.ll
@@ -3,10 +3,18 @@
 ; RUN:   | FileCheck -check-prefix=RV32 %s
 ; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+experimental-zilx -verify-machineinstrs \
 ; RUN:   | FileCheck -check-prefix=RV32-ZILX %s
+; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+zba -verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV32-ZBA %s
+; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+zba,+experimental-zilx -verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV32-ZBA-ZILX %s
 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -verify-machineinstrs \
 ; RUN:   | FileCheck -check-prefix=RV64 %s
 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+experimental-zilx -verify-machineinstrs \
 ; RUN:   | FileCheck -check-prefix=RV64-ZILX %s
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+zba -verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV64-ZBA %s
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+zba,+experimental-zilx -verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV64-ZBA-ZILX %s
 
 ;------------------------------------------------------------------------------
 ; Unscaled Load
@@ -24,6 +32,17 @@ define i8 @lxb_anyext(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxb a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxb_anyext:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lbu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxb_anyext:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxb_anyext:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -34,6 +53,17 @@ define i8 @lxb_anyext(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxb a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxb_anyext:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    lbu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxb_anyext:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxb a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i8, ptr %1, align 1
   ret i8 %2
@@ -51,6 +81,17 @@ define i32 @lxb(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxb a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxb:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lb a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxb:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxb:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -61,6 +102,17 @@ define i32 @lxb(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxb a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxb:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    lb a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxb:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxb a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i8, ptr %1, align 1
   %3 = sext i8 %2 to i32
@@ -79,6 +131,17 @@ define i8 @lxb_uw_anyext(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxb a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxb_uw_anyext:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lbu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxb_uw_anyext:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxb_uw_anyext:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -91,6 +154,17 @@ define i8 @lxb_uw_anyext(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxb.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxb_uw_anyext:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lbu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxb_uw_anyext:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxb.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i8, ptr %2, align 1
@@ -109,6 +183,17 @@ define i32 @lxb_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxb a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxb_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lb a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxb_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxb_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -121,6 +206,17 @@ define i32 @lxb_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxb.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxb_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lb a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxb_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxb.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i8, ptr %2, align 1
@@ -140,6 +236,17 @@ define i32 @lxbu(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxbu a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxbu:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lbu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxbu:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxbu:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -150,6 +257,17 @@ define i32 @lxbu(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxbu a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxbu:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    lbu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxbu:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i8, ptr %1, align 1
   %3 = zext i8 %2 to i32
@@ -168,6 +286,17 @@ define i32 @lxbu_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxbu a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxbu_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lbu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxbu_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxbu_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -180,6 +309,17 @@ define i32 @lxbu_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxbu.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxbu_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lbu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxbu_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxbu.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i8, ptr %2, align 1
@@ -199,6 +339,17 @@ define i16 @lxh(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxh a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -209,6 +360,17 @@ define i16 @lxh(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxh a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxh a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i16, ptr %1, align 2
   ret i16 %2
@@ -226,6 +388,17 @@ define i16 @lxh_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxh a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -238,6 +411,17 @@ define i16 @lxh_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxh.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxh.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i16, ptr %2, align 2
@@ -256,6 +440,17 @@ define i32 @lxhu(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxhu a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxhu:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lhu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxhu:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxhu a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxhu:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -266,6 +461,17 @@ define i32 @lxhu(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxhu a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxhu:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    lhu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxhu:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxhu a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i16, ptr %1, align 2
   %3 = zext i16 %2 to i32
@@ -284,6 +490,17 @@ define i32 @lxhu_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxhu a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxhu_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lhu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxhu_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxhu a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxhu_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -296,6 +513,17 @@ define i32 @lxhu_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxhu.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxhu_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lhu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxhu_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxhu.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i16, ptr %2, align 2
@@ -315,6 +543,17 @@ define i32 @lxw(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -325,6 +564,17 @@ define i32 @lxw(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i32, ptr %1, align 4
   ret i32 %2
@@ -342,6 +592,17 @@ define i32 @lxw_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -354,6 +615,17 @@ define i32 @lxw_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxw.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxw.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i32, ptr %2, align 4
@@ -374,6 +646,19 @@ define i64 @lxwu(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    li a1, 0
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxwu:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    li a1, 0
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxwu:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    li a1, 0
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxwu:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -384,6 +669,17 @@ define i64 @lxwu(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxwu a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxwu:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    lwu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxwu:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxwu a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i32, ptr %1, align 4
   %3 = zext i32 %2 to i64
@@ -404,6 +700,19 @@ define i64 @lxwu_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    li a1, 0
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxwu_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a0, a0, a1
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    li a1, 0
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxwu_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    li a1, 0
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxwu_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -416,6 +725,17 @@ define i64 @lxwu_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxwu.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxwu_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lwu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxwu_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxwu.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i32, ptr %2, align 4
@@ -438,6 +758,20 @@ define i64 @lxd(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lw a1, 4(a1)
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxd:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a1, a0, a1
+; RV32-ZBA-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxd:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    add a1, a0, a1
+; RV32-ZBA-ZILX-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-ZILX-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxd:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    add a0, a0, a1
@@ -448,6 +782,17 @@ define i64 @lxd(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxd a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxd:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add a0, a0, a1
+; RV64-ZBA-NEXT:    ld a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxd:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxd a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i8, ptr %a, iXLen %b
   %2 = load i64, ptr %1, align 8
   ret i64 %2
@@ -468,6 +813,20 @@ define i64 @lxd_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lw a1, 4(a1)
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxd_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    add a1, a0, a1
+; RV32-ZBA-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxd_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    add a1, a0, a1
+; RV32-ZBA-ZILX-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-ZILX-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxd_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -480,6 +839,17 @@ define i64 @lxd_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxd.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxd_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    ld a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxd_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxd.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i8, ptr %a, i64 %1
   %3 = load i64, ptr %2, align 8
@@ -503,6 +873,17 @@ define i16 @lxh_s_anyext(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxh.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh_s_anyext:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh_s_anyext:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxh.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh_s_anyext:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 1
@@ -514,6 +895,17 @@ define i16 @lxh_s_anyext(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxh.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh_s_anyext:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add a0, a1, a0
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh_s_anyext:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxh.s a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i16, ptr %a, iXLen %b
   %2 = load i16, ptr %1, align 2
   ret i16 %2
@@ -532,6 +924,17 @@ define i32 @lxh_s(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxh.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh_s:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh_s:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxh.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh_s:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 1
@@ -543,6 +946,17 @@ define i32 @lxh_s(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxh.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh_s:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add a0, a1, a0
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh_s:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxh.s a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i16, ptr %a, iXLen %b
   %2 = load i16, ptr %1, align 2
   %3 = sext i16 %2 to i32
@@ -562,6 +976,17 @@ define i16 @lxh_s_uw_anyext(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxh.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh_s_uw_anyext:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh_s_uw_anyext:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxh.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh_s_uw_anyext:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -574,6 +999,17 @@ define i16 @lxh_s_uw_anyext(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxh.s.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh_s_uw_anyext:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh_s_uw_anyext:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxh.s.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i16, ptr %a, i64 %1
   %3 = load i16, ptr %2, align 2
@@ -593,6 +1029,17 @@ define i32 @lxh_s_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxh.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh_s_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh_s_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxh.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh_s_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -605,6 +1052,17 @@ define i32 @lxh_s_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxh.s.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh_s_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh_s_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxh.s.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i16, ptr %a, i64 %1
   %3 = load i16, ptr %2, align 2
@@ -625,6 +1083,17 @@ define i32 @lxhu_s(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxhu.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxhu_s:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lhu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxhu_s:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxhu.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxhu_s:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 1
@@ -636,6 +1105,17 @@ define i32 @lxhu_s(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxhu.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxhu_s:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add a0, a1, a0
+; RV64-ZBA-NEXT:    lhu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxhu_s:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxhu.s a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i16, ptr %a, iXLen %b
   %2 = load i16, ptr %1, align 2
   %3 = zext i16 %2 to i32
@@ -655,6 +1135,17 @@ define i32 @lxhu_s_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxhu.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxhu_s_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lhu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxhu_s_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxhu.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxhu_s_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -667,6 +1158,17 @@ define i32 @lxhu_s_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxhu.s.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxhu_s_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lhu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxhu_s_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxhu.s.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i16, ptr %a, i64 %1
   %3 = load i16, ptr %2, align 2
@@ -687,6 +1189,17 @@ define i32 @lxw_s_anyext(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxw.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s_anyext:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s_anyext:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s_anyext:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 2
@@ -698,6 +1211,17 @@ define i32 @lxw_s_anyext(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxw.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s_anyext:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s_anyext:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i32, ptr %a, iXLen %b
   %2 = load i32, ptr %1, align 4
   ret i32 %2
@@ -718,6 +1242,19 @@ define i64 @lxw_s(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    srai a1, a0, 31
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    srai a1, a0, 31
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    srai a1, a0, 31
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 2
@@ -729,6 +1266,17 @@ define i64 @lxw_s(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxw.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i32, ptr %a, iXLen %b
   %2 = load i32, ptr %1, align 4
   %3 = sext i32 %2 to i64
@@ -748,6 +1296,17 @@ define i32 @lxw_s_uw_anyext(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxw.s a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s_uw_anyext:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s_uw_anyext:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s_uw_anyext:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -760,6 +1319,17 @@ define i32 @lxw_s_uw_anyext(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxw.s.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s_uw_anyext:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s_uw_anyext:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxw.s.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i32, ptr %a, i64 %1
   %3 = load i32, ptr %2, align 4
@@ -781,6 +1351,19 @@ define i64 @lxw_s_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    srai a1, a0, 31
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    srai a1, a0, 31
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    srai a1, a0, 31
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -793,6 +1376,17 @@ define i64 @lxw_s_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxw.s.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxw.s.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i32, ptr %a, i64 %1
   %3 = load i32, ptr %2, align 4
@@ -815,6 +1409,19 @@ define i64 @lxwu_s(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    li a1, 0
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxwu_s:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    li a1, 0
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxwu_s:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    li a1, 0
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxwu_s:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 2
@@ -826,6 +1433,17 @@ define i64 @lxwu_s(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxwu.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxwu_s:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add a0, a1, a0
+; RV64-ZBA-NEXT:    lwu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxwu_s:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxwu.s a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i32, ptr %a, iXLen %b
   %2 = load i32, ptr %1, align 4
   %3 = zext i32 %2 to i64
@@ -847,6 +1465,19 @@ define i64 @lxwu_s_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    li a1, 0
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxwu_s_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    li a1, 0
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxwu_s_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    lxw.s a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    li a1, 0
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxwu_s_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -859,6 +1490,17 @@ define i64 @lxwu_s_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxwu.s.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxwu_s_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lwu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxwu_s_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxwu.s.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i32, ptr %a, i64 %1
   %3 = load i32, ptr %2, align 4
@@ -883,6 +1525,20 @@ define i64 @lxd_s(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lw a1, 4(a1)
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxd_s:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh3add a1, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxd_s:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    sh3add a1, a1, a0
+; RV32-ZBA-ZILX-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-ZILX-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxd_s:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 3
@@ -894,6 +1550,17 @@ define i64 @lxd_s(ptr %a, iXLen %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxd.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxd_s:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh3add a0, a1, a0
+; RV64-ZBA-NEXT:    ld a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxd_s:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxd.s a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i64, ptr %a, iXLen %b
   %2 = load i64, ptr %1, align 8
   ret i64 %2
@@ -916,6 +1583,20 @@ define i64 @lxd_s_2(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lw a1, 100(a1)
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxd_s_2:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh3add a1, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 96(a1)
+; RV32-ZBA-NEXT:    lw a1, 100(a1)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxd_s_2:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    sh3add a1, a1, a0
+; RV32-ZBA-ZILX-NEXT:    lw a0, 96(a1)
+; RV32-ZBA-ZILX-NEXT:    lw a1, 100(a1)
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxd_s_2:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 3
@@ -928,6 +1609,18 @@ define i64 @lxd_s_2(ptr %a, iXLen %b) {
 ; RV64-ZILX-NEXT:    addi a0, a0, 96
 ; RV64-ZILX-NEXT:    lxd.s a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxd_s_2:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh3add a0, a1, a0
+; RV64-ZBA-NEXT:    ld a0, 96(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxd_s_2:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    sh3add a0, a1, a0
+; RV64-ZBA-ZILX-NEXT:    ld a0, 96(a0)
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = add iXLen %b, 12
   %2 = getelementptr i64, ptr %a, iXLen %1
   %3 = load i64, ptr %2, align 8
@@ -951,6 +1644,20 @@ define i64 @lxd_s_uw(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lw a1, 4(a1)
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxd_s_uw:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh3add a1, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxd_s_uw:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    sh3add a1, a1, a0
+; RV32-ZBA-ZILX-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-ZILX-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxd_s_uw:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -963,6 +1670,17 @@ define i64 @lxd_s_uw(ptr %a, i32 %b) {
 ; RV64-ZILX:       # %bb.0:
 ; RV64-ZILX-NEXT:    lxd.s.uw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxd_s_uw:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh3add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    ld a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxd_s_uw:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    lxd.s.uw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i64, ptr %a, i64 %1
   %3 = load i64, ptr %2, align 8
@@ -993,6 +1711,18 @@ define zeroext i8 @lxbu_shl_too_large(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxbu a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxbu_shl_too_large:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lbu a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxbu_shl_too_large:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    slli a1, a1, 2
+; RV32-ZBA-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxbu_shl_too_large:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 2
@@ -1005,6 +1735,18 @@ define zeroext i8 @lxbu_shl_too_large(ptr %a, iXLen %b) {
 ; RV64-ZILX-NEXT:    slli a1, a1, 2
 ; RV64-ZILX-NEXT:    lxbu a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxbu_shl_too_large:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add a0, a1, a0
+; RV64-ZBA-NEXT:    lbu a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxbu_shl_too_large:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli a1, a1, 2
+; RV64-ZBA-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i32, ptr %a, iXLen %b
   %2 = load i8, ptr %1, align 1
   ret i8 %2
@@ -1025,6 +1767,18 @@ define signext i16 @lxh_s_shl_too_large(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxh a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh_s_shl_too_large:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh_s_shl_too_large:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    slli a1, a1, 2
+; RV32-ZBA-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh_s_shl_too_large:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 2
@@ -1037,6 +1791,18 @@ define signext i16 @lxh_s_shl_too_large(ptr %a, iXLen %b) {
 ; RV64-ZILX-NEXT:    slli a1, a1, 2
 ; RV64-ZILX-NEXT:    lxh a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh_s_shl_too_large:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add a0, a1, a0
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh_s_shl_too_large:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli a1, a1, 2
+; RV64-ZBA-ZILX-NEXT:    lxh a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i32, ptr %a, iXLen %b
   %2 = load i16, ptr %1, align 2
   ret i16 %2
@@ -1057,6 +1823,18 @@ define i32 @lxw_s_shl_too_small(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s_shl_too_small:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s_shl_too_small:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    slli a1, a1, 1
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s_shl_too_small:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 1
@@ -1069,6 +1847,18 @@ define i32 @lxw_s_shl_too_small(ptr %a, iXLen %b) {
 ; RV64-ZILX-NEXT:    slli a1, a1, 1
 ; RV64-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s_shl_too_small:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s_shl_too_small:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli a1, a1, 1
+; RV64-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i16, ptr %a, iXLen %b
   %2 = load i32, ptr %1, align 4
   ret i32 %2
@@ -1089,6 +1879,18 @@ define i32 @lxw_s_shl_too_large(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s_shl_too_large:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh3add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s_shl_too_large:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    slli a1, a1, 3
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s_shl_too_large:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 3
@@ -1101,6 +1903,18 @@ define i32 @lxw_s_shl_too_large(ptr %a, iXLen %b) {
 ; RV64-ZILX-NEXT:    slli a1, a1, 3
 ; RV64-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s_shl_too_large:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh3add a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s_shl_too_large:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli a1, a1, 3
+; RV64-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i64, ptr %a, iXLen %b
   %2 = load i32, ptr %1, align 4
   ret i32 %2
@@ -1123,6 +1937,20 @@ define i64 @lxd_s_shl_too_small(ptr %a, iXLen %b) {
 ; RV32-ZILX-NEXT:    lxw.s a1, (a2), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxd_s_shl_too_small:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a1, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxd_s_shl_too_small:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    sh2add a1, a1, a0
+; RV32-ZBA-ZILX-NEXT:    lw a0, 0(a1)
+; RV32-ZBA-ZILX-NEXT:    lw a1, 4(a1)
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxd_s_shl_too_small:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 2
@@ -1135,6 +1963,18 @@ define i64 @lxd_s_shl_too_small(ptr %a, iXLen %b) {
 ; RV64-ZILX-NEXT:    slli a1, a1, 2
 ; RV64-ZILX-NEXT:    lxd a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxd_s_shl_too_small:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add a0, a1, a0
+; RV64-ZBA-NEXT:    ld a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxd_s_shl_too_small:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli a1, a1, 2
+; RV64-ZBA-ZILX-NEXT:    lxd a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = getelementptr i32, ptr %a, iXLen %b
   %2 = load i64, ptr %1, align 8
   ret i64 %2
@@ -1156,6 +1996,18 @@ define signext i16 @lxh_s_uw_shl_too_large(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxh a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxh_s_uw_shl_too_large:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh2add a0, a1, a0
+; RV32-ZBA-NEXT:    lh a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxh_s_uw_shl_too_large:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    slli a1, a1, 2
+; RV32-ZBA-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxh_s_uw_shl_too_large:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -1170,6 +2022,18 @@ define signext i16 @lxh_s_uw_shl_too_large(ptr %a, i32 %b) {
 ; RV64-ZILX-NEXT:    srli a1, a1, 30
 ; RV64-ZILX-NEXT:    lxh a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxh_s_uw_shl_too_large:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh2add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lh a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxh_s_uw_shl_too_large:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli.uw a1, a1, 2
+; RV64-ZBA-ZILX-NEXT:    lxh a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i32, ptr %a, i64 %1
   %3 = load i16, ptr %2, align 2
@@ -1192,6 +2056,18 @@ define i32 @lxw_s_uw_shl_too_small(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s_uw_shl_too_small:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh1add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s_uw_shl_too_small:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    slli a1, a1, 1
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s_uw_shl_too_small:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -1206,6 +2082,18 @@ define i32 @lxw_s_uw_shl_too_small(ptr %a, i32 %b) {
 ; RV64-ZILX-NEXT:    srli a1, a1, 31
 ; RV64-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s_uw_shl_too_small:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh1add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s_uw_shl_too_small:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli.uw a1, a1, 1
+; RV64-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i16, ptr %a, i64 %1
   %3 = load i32, ptr %2, align 4
@@ -1228,6 +2116,18 @@ define i32 @lxw_s_uw_shl_too_large(ptr %a, i32 %b) {
 ; RV32-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV32-ZILX-NEXT:    ret
 ;
+; RV32-ZBA-LABEL: lxw_s_uw_shl_too_large:
+; RV32-ZBA:       # %bb.0:
+; RV32-ZBA-NEXT:    sh3add a0, a1, a0
+; RV32-ZBA-NEXT:    lw a0, 0(a0)
+; RV32-ZBA-NEXT:    ret
+;
+; RV32-ZBA-ZILX-LABEL: lxw_s_uw_shl_too_large:
+; RV32-ZBA-ZILX:       # %bb.0:
+; RV32-ZBA-ZILX-NEXT:    slli a1, a1, 3
+; RV32-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZBA-ZILX-NEXT:    ret
+;
 ; RV64-LABEL: lxw_s_uw_shl_too_large:
 ; RV64:       # %bb.0:
 ; RV64-NEXT:    slli a1, a1, 32
@@ -1242,6 +2142,18 @@ define i32 @lxw_s_uw_shl_too_large(ptr %a, i32 %b) {
 ; RV64-ZILX-NEXT:    srli a1, a1, 29
 ; RV64-ZILX-NEXT:    lxw a0, (a0), a1
 ; RV64-ZILX-NEXT:    ret
+;
+; RV64-ZBA-LABEL: lxw_s_uw_shl_too_large:
+; RV64-ZBA:       # %bb.0:
+; RV64-ZBA-NEXT:    sh3add.uw a0, a1, a0
+; RV64-ZBA-NEXT:    lw a0, 0(a0)
+; RV64-ZBA-NEXT:    ret
+;
+; RV64-ZBA-ZILX-LABEL: lxw_s_uw_shl_too_large:
+; RV64-ZBA-ZILX:       # %bb.0:
+; RV64-ZBA-ZILX-NEXT:    slli.uw a1, a1, 3
+; RV64-ZBA-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZBA-ZILX-NEXT:    ret
   %1 = zext i32 %b to i64
   %2 = getelementptr i64, ptr %a, i64 %1
   %3 = load i32, ptr %2, align 4

>From fcc1d9a2d684ce8a77f055db6f971f57f428f77c Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Mon, 27 Jul 2026 18:56:32 +0800
Subject: [PATCH 06/10] Only ISD::LOAD for Zilx in isRegRegScaleLoadOrStore

Created using spr 1.3.6-beta.1
---
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 1813f13946b56..0bae347941758 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3759,9 +3759,12 @@ static bool isRegRegScaleLoadOrStore(SDNode *User, SDValue Add,
   if (User->getOpcode() != ISD::LOAD && User->getOpcode() != ISD::STORE)
     return false;
   EVT VT = cast<MemSDNode>(User)->getMemoryVT();
-  if (!(VT.isScalarInteger() &&
-        (Subtarget.hasStdExtZilx() || Subtarget.hasVendorXTHeadMemIdx() ||
-         Subtarget.hasVendorXqcisls())) &&
+  // Zilx only provides indexed loads, so it must not enable reg+reg-scale
+  // address folding for stores. XTheadMemIdx and Xqcisls have scaled stores.
+  bool HasScalarIntegerMemIdx =
+      Subtarget.hasVendorXTHeadMemIdx() || Subtarget.hasVendorXqcisls() ||
+      (Subtarget.hasStdExtZilx() && User->getOpcode() == ISD::LOAD);
+  if (!(VT.isScalarInteger() && HasScalarIntegerMemIdx) &&
       !((VT == MVT::f32 || VT == MVT::f64) &&
         Subtarget.hasVendorXTHeadFMemIdx()))
     return false;

>From 6592a6bd8f1d7bc725df4aa3a277a9bcec25f876 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Mon, 27 Jul 2026 19:32:03 +0800
Subject: [PATCH 07/10] Introduce UserOpc = User->getOpcode()

Created using spr 1.3.6-beta.1
---
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 0bae347941758..f36f27769a353 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3756,21 +3756,21 @@ bool RISCVDAGToDAGISel::SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base,
 /// Return true if this a load/store that we have a RegRegScale instruction for.
 static bool isRegRegScaleLoadOrStore(SDNode *User, SDValue Add,
                                      const RISCVSubtarget &Subtarget) {
-  if (User->getOpcode() != ISD::LOAD && User->getOpcode() != ISD::STORE)
+  unsigned UserOpc = User->getOpcode();
+  if (UserOpc != ISD::LOAD && UserOpc != ISD::STORE)
     return false;
   EVT VT = cast<MemSDNode>(User)->getMemoryVT();
   // Zilx only provides indexed loads, so it must not enable reg+reg-scale
   // address folding for stores. XTheadMemIdx and Xqcisls have scaled stores.
   bool HasScalarIntegerMemIdx =
       Subtarget.hasVendorXTHeadMemIdx() || Subtarget.hasVendorXqcisls() ||
-      (Subtarget.hasStdExtZilx() && User->getOpcode() == ISD::LOAD);
+      (Subtarget.hasStdExtZilx() && UserOpc == ISD::LOAD);
   if (!(VT.isScalarInteger() && HasScalarIntegerMemIdx) &&
       !((VT == MVT::f32 || VT == MVT::f64) &&
         Subtarget.hasVendorXTHeadFMemIdx()))
     return false;
   // Don't allow stores of the value. It must be used as the address.
-  if (User->getOpcode() == ISD::STORE &&
-      cast<StoreSDNode>(User)->getValue() == Add)
+  if (UserOpc == ISD::STORE && cast<StoreSDNode>(User)->getValue() == Add)
     return false;
 
   return true;

>From e6d0532f845fc1beb9b67a336fde5e9cd2a13d63 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Tue, 28 Jul 2026 11:25:07 +0800
Subject: [PATCH 08/10] Use std::array and merge release notes

Created using spr 1.3.6-beta.1
---
 llvm/docs/ReleaseNotes.md                 | 4 ++--
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 2c1b769578e38..07990a93c2cb1 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -91,8 +91,8 @@ Makes programs 10x faster by doing Special New Thing.
 
 ### Changes to the RISC-V Backend
 
-* Adds experimental assembler support for the `Zilx` (Indexed Integer Load) extension.
-* Adds experimental CodeGen support for the `Zilx` (Indexed Integer Load) extension.
+* Adds experimental assembler/CodeGen support for the `Zilx` (Indexed Integer
+  Load) extension.
 
 ### Changes to the WebAssembly Backend
 
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 8bd362d770a7a..fabd32750a73e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -69,7 +69,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
   template <unsigned MaxShift>
   bool SelectAddrRegRegScale(SDValue Addr, SDValue &Base, SDValue &Index,
                              SDValue &Scale) {
-    SmallVector<unsigned> Amounts(MaxShift + 1);
+    std::array<unsigned, MaxShift + 1> Amounts;
     std::iota(Amounts.begin(), Amounts.end(), 0);
     return SelectAddrRegRegScale(Addr, Amounts, Base, Index, Scale);
   }
@@ -92,7 +92,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
   template <unsigned MaxShift, unsigned Bits>
   bool SelectAddrRegZextRegScale(SDValue Addr, SDValue &Base, SDValue &Index,
                                  SDValue &Scale) {
-    SmallVector<unsigned> Amounts(MaxShift + 1);
+    std::array<unsigned, MaxShift + 1> Amounts;
     std::iota(Amounts.begin(), Amounts.end(), 0);
     return SelectAddrRegZextRegScale(Addr, Amounts, Bits, Base, Index, Scale);
   }

>From 45b3492eeaf09020b27fd20a371166547532273e Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Tue, 28 Jul 2026 16:38:53 +0800
Subject: [PATCH 09/10] Add IsSignExtendingOpW = 1

Created using spr 1.3.6-beta.1
---
 llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td   |   9 ++
 llvm/test/CodeGen/RISCV/zilx-opt-w-instrs.mir | 110 ++++++++++++++++++
 2 files changed, 119 insertions(+)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
index 280eca8c39518..a74825006cbff 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
@@ -31,6 +31,7 @@ class ZilxLoad<bits<5> funct5, bits<3> funct3, string opcodestr>
 //===----------------------------------------------------------------------===//
 
 let Predicates = [HasStdExtZilx] in {
+let IsSignExtendingOpW = 1 in {
 // Unscaled indexed loads: address = base + index. Byte loads are not provided
 // in the unscaled mode.
 def LXH  : ZilxLoad<0b10010, 0b001, "lxh">,
@@ -52,6 +53,7 @@ def LXSBU : ZilxLoad<0b11010, 0b100, "lxsbu">,
             Sched<[WriteLDB, ReadMemBase, ReadMemBase]>;
 def LXSHU : ZilxLoad<0b11010, 0b101, "lxshu">,
             Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+} // IsSignExtendingOpW = 1
 
 let append Predicates = [IsRV64] in {
 // Unscaled indexed loads (RV64-only widths).
@@ -68,18 +70,25 @@ def LXSWU : ZilxLoad<0b11010, 0b110, "lxswu">,
 
 // Scaled indexed loads with a zero-extended 32-bit index (RV64-only):
 // address = base + (zext32(index) << log2(access-size)).
+let IsSignExtendingOpW = 1 in {
 def LXSUWB  : ZilxLoad<0b11110, 0b000, "lxsuwb">,
               Sched<[WriteLDB, ReadMemBase, ReadMemBase]>;
 def LXSUWH  : ZilxLoad<0b11110, 0b001, "lxsuwh">,
               Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
 def LXSUWW  : ZilxLoad<0b11110, 0b010, "lxsuww">,
               Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
+} // IsSignExtendingOpW = 1
+
 def LXSUWD  : ZilxLoad<0b11110, 0b011, "lxsuwd">,
               Sched<[WriteLDD, ReadMemBase, ReadMemBase]>;
+
+let IsSignExtendingOpW = 1 in {
 def LXSUWBU : ZilxLoad<0b11110, 0b100, "lxsuwbu">,
               Sched<[WriteLDB, ReadMemBase, ReadMemBase]>;
 def LXSUWHU : ZilxLoad<0b11110, 0b101, "lxsuwhu">,
               Sched<[WriteLDH, ReadMemBase, ReadMemBase]>;
+} // IsSignExtendingOpW = 1
+
 def LXSUWWU : ZilxLoad<0b11110, 0b110, "lxsuwwu">,
               Sched<[WriteLDW, ReadMemBase, ReadMemBase]>;
 } // append Predicates = [IsRV64]
diff --git a/llvm/test/CodeGen/RISCV/zilx-opt-w-instrs.mir b/llvm/test/CodeGen/RISCV/zilx-opt-w-instrs.mir
index 0cd0a40feb6e2..b620a5371d74d 100644
--- a/llvm/test/CodeGen/RISCV/zilx-opt-w-instrs.mir
+++ b/llvm/test/CodeGen/RISCV/zilx-opt-w-instrs.mir
@@ -70,3 +70,113 @@ body:             |
     $x10 = COPY %3
     PseudoRET implicit $x10
 ...
+
+# The byte, halfword, and signed word loads are marked IsSignExtendingOpW, so
+# a sext.w that consumes their result is redundant and gets removed.
+
+---
+name:            lxh_sextw_removed
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x10, $x11
+    ; CHECK-LABEL: name: lxh_sextw_removed
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[LXH:%[0-9]+]]:gpr = LXH [[COPY]], [[COPY1]] :: (load (s16))
+    ; CHECK-NEXT: $x10 = COPY [[LXH]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gpr = COPY $x10
+    %1:gpr = COPY $x11
+    %2:gpr = LXH %0, %1 :: (load (s16))
+    %3:gpr = ADDIW %2, 0
+    $x10 = COPY %3
+    PseudoRET implicit $x10
+...
+---
+name:            lxsb_sextw_removed
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x10, $x11
+    ; CHECK-LABEL: name: lxsb_sextw_removed
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[LXSB:%[0-9]+]]:gpr = LXSB [[COPY]], [[COPY1]] :: (load (s8))
+    ; CHECK-NEXT: $x10 = COPY [[LXSB]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gpr = COPY $x10
+    %1:gpr = COPY $x11
+    %2:gpr = LXSB %0, %1 :: (load (s8))
+    %3:gpr = ADDIW %2, 0
+    $x10 = COPY %3
+    PseudoRET implicit $x10
+...
+---
+name:            lxshu_sextw_removed
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x10, $x11
+    ; CHECK-LABEL: name: lxshu_sextw_removed
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[LXSHU:%[0-9]+]]:gpr = LXSHU [[COPY]], [[COPY1]] :: (load (s16))
+    ; CHECK-NEXT: $x10 = COPY [[LXSHU]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gpr = COPY $x10
+    %1:gpr = COPY $x11
+    %2:gpr = LXSHU %0, %1 :: (load (s16))
+    %3:gpr = ADDIW %2, 0
+    $x10 = COPY %3
+    PseudoRET implicit $x10
+...
+---
+name:            lxsuww_sextw_removed
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x10, $x11
+    ; CHECK-LABEL: name: lxsuww_sextw_removed
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[LXSUWW:%[0-9]+]]:gpr = LXSUWW [[COPY]], [[COPY1]] :: (load (s32))
+    ; CHECK-NEXT: $x10 = COPY [[LXSUWW]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gpr = COPY $x10
+    %1:gpr = COPY $x11
+    %2:gpr = LXSUWW %0, %1 :: (load (s32))
+    %3:gpr = ADDIW %2, 0
+    $x10 = COPY %3
+    PseudoRET implicit $x10
+...
+---
+name:            lxsuwwu_sextw_kept
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x10, $x11
+    ; CHECK-LABEL: name: lxsuwwu_sextw_kept
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11
+    ; CHECK-NEXT: [[LXSUWWU:%[0-9]+]]:gpr = LXSUWWU [[COPY]], [[COPY1]] :: (load (s32))
+    ; CHECK-NEXT: [[ADDIW:%[0-9]+]]:gpr = ADDIW [[LXSUWWU]], 0
+    ; CHECK-NEXT: $x10 = COPY [[ADDIW]]
+    ; CHECK-NEXT: PseudoRET implicit $x10
+    %0:gpr = COPY $x10
+    %1:gpr = COPY $x11
+    %2:gpr = LXSUWWU %0, %1 :: (load (s32))
+    %3:gpr = ADDIW %2, 0
+    $x10 = COPY %3
+    PseudoRET implicit $x10
+...

>From 5c647f20a4d9603e0d6ba52b2da078d5bba32e12 Mon Sep 17 00:00:00 2001
From: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
Date: Wed, 29 Jul 2026 14:41:59 +0800
Subject: [PATCH 10/10] Reword comments

Created using spr 1.3.6-beta.1
---
 llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
index a74825006cbff..4555c07b1d850 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
@@ -113,11 +113,11 @@ def : InstAlias<"lxbu $rd, $rs2, $rs1", (LXSBU GPR:$rd, GPRMemZeroOffset:$rs2, G
 // base L{B,H,W,D}[U] patterns (which also match a "reg + reg" address as
 // base+0) and, being listed later, would never be selected. The required
 // ordering is:
-//   base L*  <  scale-0 (unscaled) Zilx  <  scaled Zilx
-// For a given load only the scale-0 form (which leaves the shift as a separate
-// slli) and the exactly-matching scaled form can compete, so a scaled load
-// only needs to outrank its own unscaled form; distinct non-zero scales never
-// compete for the same node.
+//   base L*  <  unscaled (shift-amount 0) Zilx  <  scaled Zilx
+// For a given load only the shift-amount-0 form (which leaves the shift as a
+// separate slli) and the exactly-matching scaled form can compete, so a scaled
+// load only needs to outrank its own unscaled form; distinct non-zero shift
+// amounts never compete for the same node.
 class AddrRegReg<int N>
     : ComplexPattern<iPTR, 2, "SelectAddrRegRegFixedScale<"#N#">",
                      [], [], !if(!eq(N, 0), 10, 11)>;
@@ -156,7 +156,8 @@ class ScaledZextIndexLoadPat<PatFrag LoadOp, RVInst Inst, int Scale, ValueType v
 
 // Patterns
 let Predicates = [HasStdExtZilx] in {
-// Byte loads only have a scaled (scale-0) encoding.
+// Byte loads only exist in scaled form, but the byte scale factor is 1, so
+// they match with shift amount 0 (address = base + index).
 def : UnscaledIndexLoadPat<extloadi8, LXSB>;
 def : UnscaledIndexLoadPat<sextloadi8, LXSB>;
 def : UnscaledIndexLoadPat<zextloadi8, LXSBU>;
@@ -186,7 +187,7 @@ def : ScaledIndexLoadPat<zextloadi32, LXSWU, 2, i64>;
 
 def : ScaledIndexLoadPat<load, LXSD, 3, i64>;
 
-// Zero-extended 32-bit index. Byte loads use the scale-0 encoding.
+// Zero-extended 32-bit index. Byte loads match with shift amount 0.
 def : ScaledZextIndexLoadPat<extloadi8, LXSUWB, 0>;
 def : ScaledZextIndexLoadPat<sextloadi8, LXSUWB, 0>;
 def : ScaledZextIndexLoadPat<zextloadi8, LXSUWBU, 0>;



More information about the llvm-branch-commits mailing list