[RISCV] Implement codegen for XAndesPerf lea instructions (#137925)

This patch add the patterns for generating XAndesPerf lea instructions.

The operation of LEA family instructions is:

  rd = rs1 + rs2 * (the number of bytes)

The variants with *.ze suffix are RV64 only and its operation is:

  rd = rs1 + ZE32(rs2[31:0]) * (the number of bytes)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 134d82d..158a3af 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -14516,8 +14516,8 @@
 //          (SLLI (SH*ADD x, y), c0), if c1-c0 equals to [1|2|3].
 static SDValue transformAddShlImm(SDNode *N, SelectionDAG &DAG,
                                   const RISCVSubtarget &Subtarget) {
-  // Perform this optimization only in the zba extension.
-  if (!Subtarget.hasStdExtZba())
+  // Perform this optimization only in the zba/xandesperf extension.
+  if (!Subtarget.hasStdExtZba() && !Subtarget.hasVendorXAndesPerf())
     return SDValue();
 
   // Skip for vector types and larger types.
@@ -15448,8 +15448,9 @@
   if (VT != Subtarget.getXLenVT())
     return SDValue();
 
-  const bool HasShlAdd =
-      Subtarget.hasStdExtZba() || Subtarget.hasVendorXTHeadBa();
+  const bool HasShlAdd = Subtarget.hasStdExtZba() ||
+                         Subtarget.hasVendorXTHeadBa() ||
+                         Subtarget.hasVendorXAndesPerf();
 
   ConstantSDNode *CNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
   if (!CNode)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
index 2ec7684..4e01b93 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td
@@ -135,6 +135,16 @@
   let mayStore = 0;
 }
 
+class NDSRVInstLEA<bits<7> funct7, string opcodestr>
+    : RVInstR<funct7, 0b000, OPC_CUSTOM_2,
+              (outs GPR:$rd), (ins GPR:$rs2, GPR:$rs1),
+              opcodestr, "$rd, $rs1, $rs2">,
+      Sched<[WriteIALU, ReadIALU, ReadIALU]> {
+  let hasSideEffects = 0;
+  let mayLoad = 0;
+  let mayStore = 0;
+}
+
 // GP: ADDI, LB, LBU
 class NDSRVInstLBGP<bits<2> funct2, string opcodestr>
     : RVInst<(outs GPR:$rd), (ins simm18:$imm18),
@@ -321,9 +331,9 @@
 def NDS_BFOS : NDSRVInstBFO<0b011, "nds.bfos">;
 def NDS_BFOZ : NDSRVInstBFO<0b010, "nds.bfoz">;
 
-def NDS_LEA_H : NDSRVInstRR<0b0000101, "nds.lea.h">;
-def NDS_LEA_W : NDSRVInstRR<0b0000110, "nds.lea.w">;
-def NDS_LEA_D : NDSRVInstRR<0b0000111, "nds.lea.d">;
+def NDS_LEA_H : NDSRVInstLEA<0b0000101, "nds.lea.h">;
+def NDS_LEA_W : NDSRVInstLEA<0b0000110, "nds.lea.w">;
+def NDS_LEA_D : NDSRVInstLEA<0b0000111, "nds.lea.d">;
 
 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
 def NDS_ADDIGP : NDSRVInstLBGP<0b01, "nds.addigp">;
@@ -345,10 +355,10 @@
 } // Predicates = [HasVendorXAndesPerf]
 
 let Predicates = [HasVendorXAndesPerf, IsRV64] in {
-def NDS_LEA_B_ZE : NDSRVInstRR<0b0001000, "nds.lea.b.ze">;
-def NDS_LEA_H_ZE : NDSRVInstRR<0b0001001, "nds.lea.h.ze">;
-def NDS_LEA_W_ZE : NDSRVInstRR<0b0001010, "nds.lea.w.ze">;
-def NDS_LEA_D_ZE : NDSRVInstRR<0b0001011, "nds.lea.d.ze">;
+def NDS_LEA_B_ZE : NDSRVInstLEA<0b0001000, "nds.lea.b.ze">;
+def NDS_LEA_H_ZE : NDSRVInstLEA<0b0001001, "nds.lea.h.ze">;
+def NDS_LEA_W_ZE : NDSRVInstLEA<0b0001010, "nds.lea.w.ze">;
+def NDS_LEA_D_ZE : NDSRVInstLEA<0b0001011, "nds.lea.d.ze">;
 
 def NDS_LWUGP : NDSRVInstLWGP<0b110, "nds.lwugp">;
 def NDS_LDGP  : NDSRVInstLDGP<0b011, "nds.ldgp">;
@@ -356,3 +366,32 @@
 def NDS_SDGP  : NDSRVInstSDGP<0b111, "nds.sdgp">;
 } // Predicates = [HasVendorXAndesPerf, IsRV64]
 } // DecoderNamespace = "XAndes"
+
+// Patterns
+
+let Predicates = [HasVendorXAndesPerf] in {
+
+defm : ShxAddPat<1, NDS_LEA_H>;
+defm : ShxAddPat<2, NDS_LEA_W>;
+defm : ShxAddPat<3, NDS_LEA_D>;
+
+def : CSImm12MulBy4Pat<NDS_LEA_W>;
+def : CSImm12MulBy8Pat<NDS_LEA_D>;
+} // Predicates = [HasVendorXAndesPerf]
+
+let Predicates = [HasVendorXAndesPerf, IsRV64] in {
+
+defm : ADD_UWPat<NDS_LEA_B_ZE>;
+
+defm : ShxAdd_UWPat<1, NDS_LEA_H_ZE>;
+defm : ShxAdd_UWPat<2, NDS_LEA_W_ZE>;
+defm : ShxAdd_UWPat<3, NDS_LEA_D_ZE>;
+
+defm : Sh1Add_UWPat<NDS_LEA_H_ZE>;
+defm : Sh2Add_UWPat<NDS_LEA_W_ZE>;
+defm : Sh3Add_UWPat<NDS_LEA_D_ZE>;
+
+def : Sh1AddPat<NDS_LEA_H_ZE>;
+def : Sh2AddPat<NDS_LEA_W_ZE>;
+def : Sh3AddPat<NDS_LEA_D_ZE>;
+} // Predicates = [HasVendorXAndesPerf, IsRV64]
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index 9227c1b..4353e94 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -672,10 +672,7 @@
 let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in
 def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (PACKW GPR:$rs, (XLenVT X0))>;
 
-let Predicates = [HasStdExtZba] in {
-
-foreach i = {1,2,3} in {
-  defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
+multiclass ShxAddPat<int i, Instruction shxadd> {
   def : Pat<(XLenVT (add_like_non_imm12 (shl GPR:$rs1, (XLenVT i)), GPR:$rs2)),
             (shxadd GPR:$rs1, GPR:$rs2)>;
   def : Pat<(XLenVT (riscv_shl_add GPR:$rs1, (XLenVT i), GPR:$rs2)),
@@ -687,15 +684,90 @@
             (shxadd pat:$rs1, GPR:$rs2)>;
 }
 
-def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),
-          (SH2ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),
-                  GPR:$r)>;
-def : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),
-          (SH3ADD (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),
+class CSImm12MulBy4Pat<Instruction sh2add>
+    : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy4:$i),
+          (sh2add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy4:$i)),
                   GPR:$r)>;
 
+class CSImm12MulBy8Pat<Instruction sh3add>
+    : Pat<(add_like (XLenVT GPR:$r), CSImm12MulBy8:$i),
+          (sh3add (XLenVT (ADDI (XLenVT X0), CSImm12MulBy8:$i)),
+                  GPR:$r)>;
+
+let Predicates = [HasStdExtZba] in {
+foreach i = {1,2,3} in {
+  defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
+  defm : ShxAddPat<i, shxadd>;
+}
+
+def : CSImm12MulBy4Pat<SH2ADD>;
+def : CSImm12MulBy8Pat<SH3ADD>;
 } // Predicates = [HasStdExtZba]
 
+multiclass ADD_UWPat<Instruction add_uw> {
+  def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),
+            (add_uw GPR:$rs1, GPR:$rs2)>;
+  def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (add_uw GPR:$rs, (XLenVT X0))>;
+}
+
+multiclass ShxAdd_UWPat<int i, Instruction shxadd_uw> {
+  def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)),
+                                     (XLenVT GPR:$rs2))),
+            (shxadd_uw GPR:$rs1, GPR:$rs2)>;
+  def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),
+            (shxadd_uw GPR:$rs1, GPR:$rs2)>;
+
+  defvar pat = !cast<ComplexPattern>("sh"#i#"add_uw_op");
+  // More complex cases use a ComplexPattern.
+  def : Pat<(i64 (add_like_non_imm12 pat:$rs1, (XLenVT GPR:$rs2))),
+            (shxadd_uw pat:$rs1, GPR:$rs2)>;
+}
+
+multiclass Sh1Add_UWPat<Instruction sh1add_uw> {
+  def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF),
+                                     (XLenVT GPR:$rs2))),
+            (sh1add_uw GPR:$rs1, GPR:$rs2)>;
+  // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
+  def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x1FFFFFFFE),
+                                     (XLenVT GPR:$rs2))),
+            (sh1add_uw (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;
+}
+
+multiclass Sh2Add_UWPat<Instruction sh2add_uw> {
+  def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF),
+                                     (XLenVT GPR:$rs2))),
+            (sh2add_uw GPR:$rs1, GPR:$rs2)>;
+  // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
+  def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x3FFFFFFFC),
+                                     (XLenVT GPR:$rs2))),
+            (sh2add_uw (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;
+}
+
+multiclass Sh3Add_UWPat<Instruction sh3add_uw> {
+  def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8),
+                                     (XLenVT GPR:$rs2))),
+            (sh3add_uw (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
+  // Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
+  def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x7FFFFFFF8),
+                                     (XLenVT GPR:$rs2))),
+            (sh3add_uw (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;
+}
+
+class Sh1AddPat<Instruction sh1add>
+    : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE),
+                                   (XLenVT GPR:$rs2))),
+          (sh1add (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;
+
+class Sh2AddPat<Instruction sh2add>
+    : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC),
+                                   (XLenVT GPR:$rs2))),
+          (sh2add (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;
+
+class Sh3AddPat<Instruction sh3add>
+    : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8),
+                                   (XLenVT GPR:$rs2))),
+          (sh3add (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
+
 let Predicates = [HasStdExtZba, IsRV64] in {
 def : Pat<(i64 (shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt)),
           (SLLI_UW GPR:$rs1, uimm5:$shamt)>;
@@ -704,47 +776,21 @@
 def : Pat<(i64 (and GPR:$rs1, Shifted32OnesMask:$mask)),
           (SLLI_UW (XLenVT (SRLI GPR:$rs1, Shifted32OnesMask:$mask)),
                    Shifted32OnesMask:$mask)>;
-def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFF), GPR:$rs2)),
-          (ADD_UW GPR:$rs1, GPR:$rs2)>;
-def : Pat<(i64 (and GPR:$rs, 0xFFFFFFFF)), (ADD_UW GPR:$rs, (XLenVT X0))>;
+
+defm : ADD_UWPat<ADD_UW>;
 
 foreach i = {1,2,3} in {
   defvar shxadd_uw = !cast<Instruction>("SH"#i#"ADD_UW");
-  def : Pat<(i64 (add_like_non_imm12 (shl (and GPR:$rs1, 0xFFFFFFFF), (i64 i)), (XLenVT GPR:$rs2))),
-            (shxadd_uw GPR:$rs1, GPR:$rs2)>;
-  def : Pat<(i64 (riscv_shl_add (and GPR:$rs1, 0xFFFFFFFF), (i64 i), GPR:$rs2)),
-            (shxadd_uw GPR:$rs1, GPR:$rs2)>;
+  defm : ShxAdd_UWPat<i, shxadd_uw>;
 }
 
-def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 1)), 0x1FFFFFFFF), (XLenVT GPR:$rs2))),
-          (SH1ADD_UW GPR:$rs1, GPR:$rs2)>;
-def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 2)), 0x3FFFFFFFF), (XLenVT GPR:$rs2))),
-          (SH2ADD_UW GPR:$rs1, GPR:$rs2)>;
-def : Pat<(i64 (add_like_non_imm12 (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), (XLenVT GPR:$rs2))),
-          (SH3ADD_UW GPR:$rs1, GPR:$rs2)>;
+defm : Sh1Add_UWPat<SH1ADD_UW>;
+defm : Sh2Add_UWPat<SH2ADD_UW>;
+defm : Sh3Add_UWPat<SH3ADD_UW>;
 
-// More complex cases use a ComplexPattern.
-foreach i = {1,2,3} in {
-  defvar pat = !cast<ComplexPattern>("sh"#i#"add_uw_op");
-  def : Pat<(i64 (add_like_non_imm12 pat:$rs1, (XLenVT GPR:$rs2))),
-            (!cast<Instruction>("SH"#i#"ADD_UW") pat:$rs1, GPR:$rs2)>;
-}
-
-def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFE), (XLenVT GPR:$rs2))),
-          (SH1ADD (XLenVT (SRLIW GPR:$rs1, 1)), GPR:$rs2)>;
-def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFFC), (XLenVT GPR:$rs2))),
-          (SH2ADD (XLenVT (SRLIW GPR:$rs1, 2)), GPR:$rs2)>;
-def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0xFFFFFFF8), (XLenVT GPR:$rs2))),
-          (SH3ADD (XLenVT (SRLIW GPR:$rs1, 3)), GPR:$rs2)>;
-
-// Use SRLI to clear the LSBs and SHXADD_UW to mask and shift.
-def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x1FFFFFFFE), (XLenVT GPR:$rs2))),
-          (SH1ADD_UW (XLenVT (SRLI GPR:$rs1, 1)), GPR:$rs2)>;
-def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x3FFFFFFFC), (XLenVT GPR:$rs2))),
-          (SH2ADD_UW (XLenVT (SRLI GPR:$rs1, 2)), GPR:$rs2)>;
-def : Pat<(i64 (add_like_non_imm12 (and GPR:$rs1, 0x7FFFFFFF8), (XLenVT GPR:$rs2))),
-          (SH3ADD_UW (XLenVT (SRLI GPR:$rs1, 3)), GPR:$rs2)>;
-
+def : Sh1AddPat<SH1ADD>;
+def : Sh2AddPat<SH2ADD>;
+def : Sh3AddPat<SH3ADD>;
 } // Predicates = [HasStdExtZba, IsRV64]
 
 let Predicates = [HasStdExtZbcOrZbkc] in {
diff --git a/llvm/test/CodeGen/RISCV/rv32zba.ll b/llvm/test/CodeGen/RISCV/rv32zba.ll
index f8ca417..ab09910 100644
--- a/llvm/test/CodeGen/RISCV/rv32zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zba.ll
@@ -3,6 +3,8 @@
 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32I
 ; RUN: llc -mtriple=riscv32 -mattr=+m,+zba -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32ZBA
+; RUN: llc -mtriple=riscv32 -mattr=+m,+xandesperf -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefixes=CHECK,RV32XANDESPERF
 
 define signext i16 @sh1add(i64 %0, ptr %1) {
 ; RV32I-LABEL: sh1add:
@@ -17,6 +19,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a0, a2
 ; RV32ZBA-NEXT:    lh a0, 0(a0)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: sh1add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a2, a0
+; RV32XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV32XANDESPERF-NEXT:    ret
   %3 = getelementptr inbounds i16, ptr %1, i64 %0
   %4 = load i16, ptr %3
   ret i16 %4
@@ -35,6 +43,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a2
 ; RV32ZBA-NEXT:    lw a0, 0(a0)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: sh2add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a2, a0
+; RV32XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV32XANDESPERF-NEXT:    ret
   %3 = getelementptr inbounds i32, ptr %1, i64 %0
   %4 = load i32, ptr %3
   ret i32 %4
@@ -55,6 +69,13 @@
 ; RV32ZBA-NEXT:    lw a0, 0(a1)
 ; RV32ZBA-NEXT:    lw a1, 4(a1)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: sh3add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a1, a2, a0
+; RV32XANDESPERF-NEXT:    lw a0, 0(a1)
+; RV32XANDESPERF-NEXT:    lw a1, 4(a1)
+; RV32XANDESPERF-NEXT:    ret
   %3 = getelementptr inbounds i64, ptr %1, i64 %0
   %4 = load i64, ptr %3
   ret i64 %4
@@ -74,6 +95,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a0, a0
 ; RV32ZBA-NEXT:    sh1add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul6:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 6
   %d = add i32 %c, %b
   ret i32 %d
@@ -93,6 +120,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    sh1add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul10:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 10
   %d = add i32 %c, %b
   ret i32 %d
@@ -112,6 +145,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a0, a0
 ; RV32ZBA-NEXT:    sh2add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul12:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 12
   %d = add i32 %c, %b
   ret i32 %d
@@ -131,6 +170,12 @@
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    sh1add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul18:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 18
   %d = add i32 %c, %b
   ret i32 %d
@@ -150,6 +195,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    sh2add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul20:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 20
   %d = add i32 %c, %b
   ret i32 %d
@@ -169,6 +220,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul24:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 24
   %d = add i32 %c, %b
   ret i32 %d
@@ -188,6 +245,12 @@
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    sh2add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul36:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 36
   %d = add i32 %c, %b
   ret i32 %d
@@ -207,6 +270,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul40:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 40
   %d = add i32 %c, %b
   ret i32 %d
@@ -226,6 +295,12 @@
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addmul72:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 72
   %d = add i32 %c, %b
   ret i32 %d
@@ -244,6 +319,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a0, a0
 ; RV32ZBA-NEXT:    slli a0, a0, 5
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul96:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV32XANDESPERF-NEXT:    slli a0, a0, 5
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 96
   ret i32 %c
 }
@@ -261,6 +342,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    slli a0, a0, 5
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul160:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    slli a0, a0, 5
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 160
   ret i32 %c
 }
@@ -278,6 +365,12 @@
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    slli a0, a0, 5
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul288:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    slli a0, a0, 5
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 288
   ret i32 %c
 }
@@ -295,6 +388,12 @@
 ; RV32ZBA-NEXT:    slli a1, a0, 8
 ; RV32ZBA-NEXT:    sh1add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul258:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    slli a1, a0, 8
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 258
   ret i32 %c
 }
@@ -312,6 +411,12 @@
 ; RV32ZBA-NEXT:    slli a1, a0, 8
 ; RV32ZBA-NEXT:    sh2add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul260:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    slli a1, a0, 8
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 260
   ret i32 %c
 }
@@ -329,6 +434,12 @@
 ; RV32ZBA-NEXT:    slli a1, a0, 8
 ; RV32ZBA-NEXT:    sh3add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul264:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    slli a1, a0, 8
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 264
   ret i32 %c
 }
@@ -345,6 +456,12 @@
 ; RV32ZBA-NEXT:    sh2add a1, a0, a0
 ; RV32ZBA-NEXT:    sh1add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul11:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 11
   ret i32 %c
 }
@@ -361,6 +478,12 @@
 ; RV32ZBA-NEXT:    sh3add a1, a0, a0
 ; RV32ZBA-NEXT:    sh1add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul19:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 19
   ret i32 %c
 }
@@ -377,6 +500,12 @@
 ; RV32ZBA-NEXT:    sh1add a1, a0, a0
 ; RV32ZBA-NEXT:    sh2add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul13:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a1, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 13
   ret i32 %c
 }
@@ -393,6 +522,12 @@
 ; RV32ZBA-NEXT:    sh2add a1, a0, a0
 ; RV32ZBA-NEXT:    sh2add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul21:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 21
   ret i32 %c
 }
@@ -409,6 +544,12 @@
 ; RV32ZBA-NEXT:    sh3add a1, a0, a0
 ; RV32ZBA-NEXT:    sh2add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul37:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 37
   ret i32 %c
 }
@@ -425,6 +566,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul25:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 25
   ret i32 %c
 }
@@ -441,6 +588,12 @@
 ; RV32ZBA-NEXT:    sh2add a1, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul41:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 41
   ret i32 %c
 }
@@ -457,6 +610,12 @@
 ; RV32ZBA-NEXT:    sh3add a1, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul73:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 73
   ret i32 %c
 }
@@ -473,6 +632,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul27:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 27
   ret i32 %c
 }
@@ -489,6 +654,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul45:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 45
   ret i32 %c
 }
@@ -505,6 +676,12 @@
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    sh3add a0, a0, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul81:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 81
   ret i32 %c
 }
@@ -522,6 +699,12 @@
 ; RV32ZBA-NEXT:    slli a1, a0, 12
 ; RV32ZBA-NEXT:    sh1add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul4098:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    slli a1, a0, 12
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 4098
   ret i32 %c
 }
@@ -539,6 +722,12 @@
 ; RV32ZBA-NEXT:    slli a1, a0, 12
 ; RV32ZBA-NEXT:    sh2add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul4100:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    slli a1, a0, 12
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 4100
   ret i32 %c
 }
@@ -556,6 +745,12 @@
 ; RV32ZBA-NEXT:    slli a1, a0, 12
 ; RV32ZBA-NEXT:    sh3add a0, a0, a1
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul4104:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    slli a1, a0, 12
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 4104
   ret i32 %c
 }
@@ -573,6 +768,12 @@
 ; RV32ZBA-NEXT:    li a1, 1026
 ; RV32ZBA-NEXT:    sh2add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: add4104:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    li a1, 1026
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = add i32 %a, 4104
   ret i32 %c
 }
@@ -590,6 +791,12 @@
 ; RV32ZBA-NEXT:    li a1, 1026
 ; RV32ZBA-NEXT:    sh3add a0, a1, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: add8208:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    li a1, 1026
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV32XANDESPERF-NEXT:    ret
   %c = add i32 %a, 8208
   ret i32 %c
 }
@@ -617,6 +824,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a1, a0
 ; RV32ZBA-NEXT:    slli a0, a0, 5
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addshl_5_6:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV32XANDESPERF-NEXT:    slli a0, a0, 5
+; RV32XANDESPERF-NEXT:    ret
   %c = shl i32 %a, 5
   %d = shl i32 %b, 6
   %e = add i32 %c, %d
@@ -636,6 +849,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a1, a0
 ; RV32ZBA-NEXT:    slli a0, a0, 5
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addshl_5_7:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV32XANDESPERF-NEXT:    slli a0, a0, 5
+; RV32XANDESPERF-NEXT:    ret
   %c = shl i32 %a, 5
   %d = shl i32 %b, 7
   %e = add i32 %c, %d
@@ -655,6 +874,12 @@
 ; RV32ZBA-NEXT:    sh3add a0, a1, a0
 ; RV32ZBA-NEXT:    slli a0, a0, 5
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: addshl_5_8:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV32XANDESPERF-NEXT:    slli a0, a0, 5
+; RV32XANDESPERF-NEXT:    ret
   %c = shl i32 %a, 5
   %d = shl i32 %b, 8
   %e = add i32 %c, %d
@@ -676,6 +901,13 @@
 ; RV32ZBA-NEXT:    sh2add a0, a1, a0
 ; RV32ZBA-NEXT:    lw a0, 0(a0)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: srli_1_sh2add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    srli a1, a1, 1
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV32XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV32XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 1
   %4 = getelementptr inbounds i32, ptr %0, i32 %3
   %5 = load i32, ptr %4, align 4
@@ -699,6 +931,14 @@
 ; RV32ZBA-NEXT:    lw a0, 0(a1)
 ; RV32ZBA-NEXT:    lw a1, 4(a1)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: srli_2_sh3add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    srli a1, a1, 2
+; RV32XANDESPERF-NEXT:    nds.lea.d a1, a0, a1
+; RV32XANDESPERF-NEXT:    lw a0, 0(a1)
+; RV32XANDESPERF-NEXT:    lw a1, 4(a1)
+; RV32XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 2
   %4 = getelementptr inbounds i64, ptr %0, i32 %3
   %5 = load i64, ptr %4, align 8
@@ -720,6 +960,13 @@
 ; RV32ZBA-NEXT:    sh1add a0, a1, a0
 ; RV32ZBA-NEXT:    lh a0, 0(a0)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: srli_2_sh1add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    srli a1, a1, 2
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV32XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV32XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 2
   %4 = getelementptr inbounds i16, ptr %0, i32 %3
   %5 = load i16, ptr %4, align 2
@@ -741,6 +988,13 @@
 ; RV32ZBA-NEXT:    sh2add a0, a1, a0
 ; RV32ZBA-NEXT:    lw a0, 0(a0)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: srli_3_sh2add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    srli a1, a1, 3
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV32XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV32XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 3
   %4 = getelementptr inbounds i32, ptr %0, i32 %3
   %5 = load i32, ptr %4, align 4
@@ -764,6 +1018,14 @@
 ; RV32ZBA-NEXT:    lw a0, 0(a1)
 ; RV32ZBA-NEXT:    lw a1, 4(a1)
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: srli_4_sh3add:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    srli a1, a1, 4
+; RV32XANDESPERF-NEXT:    nds.lea.d a1, a0, a1
+; RV32XANDESPERF-NEXT:    lw a0, 0(a1)
+; RV32XANDESPERF-NEXT:    lw a1, 4(a1)
+; RV32XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 4
   %4 = getelementptr inbounds i64, ptr %0, i32 %3
   %5 = load i64, ptr %4, align 8
@@ -802,6 +1064,12 @@
 ; RV32ZBA-NEXT:    sh1add a0, a0, a0
 ; RV32ZBA-NEXT:    neg a0, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul_neg3:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV32XANDESPERF-NEXT:    neg a0, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, -3
   ret i32 %c
 }
@@ -829,6 +1097,12 @@
 ; RV32ZBA-NEXT:    sh2add a0, a0, a0
 ; RV32ZBA-NEXT:    neg a0, a0
 ; RV32ZBA-NEXT:    ret
+;
+; RV32XANDESPERF-LABEL: mul_neg5:
+; RV32XANDESPERF:       # %bb.0:
+; RV32XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV32XANDESPERF-NEXT:    neg a0, a0
+; RV32XANDESPERF-NEXT:    ret
   %c = mul i32 %a, -5
   ret i32 %c
 }
diff --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index e362e5e..a023845 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -7,6 +7,8 @@
 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBAZBB,RV64ZBAZBBNOZBS
 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba,+zbb,+zbs -verify-machineinstrs < %s \
 ; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBAZBB,RV64ZBAZBBZBS
+; RUN: llc -mtriple=riscv64 -mattr=+m,+xandesperf -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64XANDESPERF
 
 define i64 @slliuw(i64 %a) nounwind {
 ; RV64I-LABEL: slliuw:
@@ -19,6 +21,12 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: slliuw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 31
+; RV64XANDESPERF-NEXT:    ret
   %conv1 = shl i64 %a, 1
   %shl = and i64 %conv1, 8589934590
   ret i64 %shl
@@ -41,6 +49,15 @@
 ; RV64ZBA-NEXT:    ld a0, 0(a1)
 ; RV64ZBA-NEXT:    ld a1, 8(a1)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: slliuw_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 28
+; RV64XANDESPERF-NEXT:    add a1, a1, a0
+; RV64XANDESPERF-NEXT:    ld a0, 0(a1)
+; RV64XANDESPERF-NEXT:    ld a1, 8(a1)
+; RV64XANDESPERF-NEXT:    ret
   %3 = zext i32 %0 to i64
   %4 = getelementptr inbounds i128, ptr %1, i64 %3
   %5 = load i128, ptr %4
@@ -59,6 +76,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    add.uw a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: adduw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %and = and i64 %b, 4294967295
   %add = add i64 %and, %a
   ret i64 %add
@@ -78,6 +100,12 @@
 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    lb a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: adduw_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    lb a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = zext i32 %0 to i64
   %4 = getelementptr inbounds i8, ptr %1, i64 %3
   %5 = load i8, ptr %4
@@ -95,6 +123,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    zext.w a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zextw_i64:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, zero, a0
+; RV64XANDESPERF-NEXT:    ret
   %and = and i64 %a, 4294967295
   ret i64 %and
 }
@@ -114,6 +147,12 @@
 ; RV64ZBA-NEXT:    ori a0, a0, 1
 ; RV64ZBA-NEXT:    zext.w a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zextw_demandedbits_i64:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    ori a0, a0, 1
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, zero, a0
+; RV64XANDESPERF-NEXT:    ret
   %2 = and i64 %0, 4294967294
   %3 = or i64 %2, 1
   ret i64 %3
@@ -132,6 +171,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh1add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = getelementptr inbounds i16, ptr %1, i64 %0
   %4 = load i16, ptr %3
   ret i16 %4
@@ -150,6 +195,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh2add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = getelementptr inbounds i32, ptr %1, i64 %0
   %4 = load i32, ptr %3
   ret i32 %4
@@ -168,6 +219,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh3add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = getelementptr inbounds i64, ptr %1, i64 %0
   %4 = load i64, ptr %3
   ret i64 %4
@@ -187,6 +244,12 @@
 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh1adduw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = zext i32 %0 to i64
   %4 = getelementptr inbounds i16, ptr %1, i64 %3
   %5 = load i16, ptr %4
@@ -205,6 +268,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh1adduw_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i64 %0, 1
   %4 = and i64 %3, 8589934590
   %5 = add i64 %4, %1
@@ -223,6 +291,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh1adduw_3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i64 %0, 1
   %4 = and i64 %3, 8589934590
   %5 = or disjoint i64 %4, %1
@@ -243,6 +316,12 @@
 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh2adduw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = zext i32 %0 to i64
   %4 = getelementptr inbounds i32, ptr %1, i64 %3
   %5 = load i32, ptr %4
@@ -261,6 +340,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh2adduw_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i64 %0, 2
   %4 = and i64 %3, 17179869180
   %5 = add i64 %4, %1
@@ -279,6 +363,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh2adduw_3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i64 %0, 2
   %4 = and i64 %3, 17179869180
   %5 = or disjoint i64 %4, %1
@@ -299,6 +388,12 @@
 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh3adduw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = zext i32 %0 to i64
   %4 = getelementptr inbounds i64, ptr %1, i64 %3
   %5 = load i64, ptr %4
@@ -315,8 +410,17 @@
 ;
 ; RV64ZBA-LABEL: sh3adduw_2:
 ; RV64ZBA:       # %bb.0:
+; RV64ZBA-NEXT:    slli a0, a0, 3
+; RV64ZBA-NEXT:    srli a0, a0, 3
 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh3adduw_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 3
+; RV64XANDESPERF-NEXT:    srli a0, a0, 3
+; RV64XANDESPERF-NEXT:    nds.lea.d.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i64 %0, 3
   %4 = and i64 %3, 34359738360
   %5 = add i64 %4, %1
@@ -333,8 +437,17 @@
 ;
 ; RV64ZBA-LABEL: sh3adduw_3:
 ; RV64ZBA:       # %bb.0:
+; RV64ZBA-NEXT:    slli a0, a0, 3
+; RV64ZBA-NEXT:    srli a0, a0, 3
 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh3adduw_3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 3
+; RV64XANDESPERF-NEXT:    srli a0, a0, 3
+; RV64XANDESPERF-NEXT:    nds.lea.d.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i64 %0, 3
   %4 = and i64 %3, 34359738360
   %5 = or disjoint i64 %4, %1
@@ -363,6 +476,14 @@
 ; RV64ZBA-NEXT:    sraiw a0, a0, 2
 ; RV64ZBA-NEXT:    mul a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh2add_extra_sext:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    sllw a1, a2, a0
+; RV64XANDESPERF-NEXT:    sraiw a0, a0, 2
+; RV64XANDESPERF-NEXT:    mul a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %a = shl i32 %x, 2
   %b = add i32 %a, %y
   %c = shl i32 %z, %b
@@ -387,6 +508,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul6:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 6
   %d = add i64 %c, %b
   ret i64 %d
@@ -406,6 +533,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: disjointormul6:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 6
   %d = or disjoint i64 %c, %b
   ret i64 %d
@@ -425,6 +558,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul10:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 10
   %d = add i64 %c, %b
   ret i64 %d
@@ -444,6 +583,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul12:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 12
   %d = add i64 %c, %b
   ret i64 %d
@@ -463,6 +608,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul18:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 18
   %d = add i64 %c, %b
   ret i64 %d
@@ -482,6 +633,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul20:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 20
   %d = add i64 %c, %b
   ret i64 %d
@@ -513,6 +670,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul24:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 24
   %d = add i64 %c, %b
   ret i64 %d
@@ -532,6 +695,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul36:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 36
   %d = add i64 %c, %b
   ret i64 %d
@@ -551,6 +720,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul40:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 40
   %d = add i64 %c, %b
   ret i64 %d
@@ -570,6 +745,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul72:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 72
   %d = add i64 %c, %b
   ret i64 %d
@@ -588,6 +769,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul50:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 50
   ret i64 %c
 }
@@ -606,6 +794,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul50:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 50
   %d = add i64 %c, %b
   ret i64 %d
@@ -624,6 +819,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 2
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul100:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 2
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 100
   ret i64 %c
 }
@@ -642,6 +844,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul100:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 100
   %d = add i64 %c, %b
   ret i64 %d
@@ -660,6 +869,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul162:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 162
   ret i64 %c
 }
@@ -678,6 +894,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul162:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 162
   %d = add i64 %c, %b
   ret i64 %d
@@ -696,6 +919,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 2
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul180:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 2
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 180
   ret i64 %c
 }
@@ -714,6 +944,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul180:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 180
   %d = add i64 %c, %b
   ret i64 %d
@@ -734,6 +971,14 @@
 ; RV64ZBA-NEXT:    slli a0, a0, 2
 ; RV64ZBA-NEXT:    addi a0, a0, 255
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: add255mul180:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 2
+; RV64XANDESPERF-NEXT:    addi a0, a0, 255
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 180
   %d = add i64 %c, 255
   ret i64 %d
@@ -752,6 +997,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 3
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul200:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 3
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 200
   ret i64 %c
 }
@@ -770,6 +1022,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addmul200:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 200
   %d = add i64 %c, %b
   ret i64 %d
@@ -812,6 +1071,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul96:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 96
   ret i64 %c
 }
@@ -829,6 +1094,13 @@
 ; RV64ZBA-NEXT:    slli a0, a0, 7
 ; RV64ZBA-NEXT:    sub a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul119:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 7
+; RV64XANDESPERF-NEXT:    sub a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 119
   ret i64 %c
 }
@@ -846,6 +1118,13 @@
 ; RV64ZBA-NEXT:    slli a0, a0, 7
 ; RV64ZBA-NEXT:    sub a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul123:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 7
+; RV64XANDESPERF-NEXT:    sub a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 123
   ret i64 %c
 }
@@ -863,6 +1142,13 @@
 ; RV64ZBA-NEXT:    slli a0, a0, 7
 ; RV64ZBA-NEXT:    sub a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul125:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a1, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 7
+; RV64XANDESPERF-NEXT:    sub a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 125
   ret i64 %c
 }
@@ -880,6 +1166,13 @@
 ; RV64ZBA-NEXT:    slli a0, a0, 7
 ; RV64ZBA-NEXT:    add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul131:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a1, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 7
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 131
   ret i64 %c
 }
@@ -897,6 +1190,13 @@
 ; RV64ZBA-NEXT:    slli a0, a0, 7
 ; RV64ZBA-NEXT:    add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul133:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 7
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 133
   ret i64 %c
 }
@@ -914,6 +1214,13 @@
 ; RV64ZBA-NEXT:    slli a0, a0, 7
 ; RV64ZBA-NEXT:    add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul137:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 7
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 137
   ret i64 %c
 }
@@ -931,6 +1238,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul160:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 160
   ret i64 %c
 }
@@ -948,6 +1261,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul288:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 288
   ret i64 %c
 }
@@ -966,6 +1285,13 @@
 ; RV64ZBA-NEXT:    slli.uw a1, a0, 6
 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zext_mul68:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a0, 32
+; RV64XANDESPERF-NEXT:    srli a1, a1, 26
+; RV64XANDESPERF-NEXT:    nds.lea.w.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %b = zext i32 %a to i64
   %c = mul i64 %b, 68
   ret i64 %c
@@ -985,6 +1311,13 @@
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zext_mul96:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 27
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %b = zext i32 %a to i64
   %c = mul i64 %b, 96
   ret i64 %c
@@ -1004,6 +1337,13 @@
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zext_mul160:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 27
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %b = zext i32 %a to i64
   %c = mul i64 %b, 160
   ret i64 %c
@@ -1023,6 +1363,13 @@
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zext_mul288:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 27
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %b = zext i32 %a to i64
   %c = mul i64 %b, 288
   ret i64 %c
@@ -1042,6 +1389,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 32
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zext_mul12884901888:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    ret
   %b = zext i32 %a to i64
   %c = mul i64 %b, 12884901888
   ret i64 %c
@@ -1061,6 +1414,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 32
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zext_mul21474836480:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    ret
   %b = zext i32 %a to i64
   %c = mul i64 %b, 21474836480
   ret i64 %c
@@ -1080,6 +1439,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 32
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: zext_mul38654705664:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    ret
   %b = zext i32 %a to i64
   %c = mul i64 %b, 38654705664
   ret i64 %c
@@ -1131,6 +1496,13 @@
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
 ; RV64ZBA-NEXT:    addi a0, a0, 11
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh1adduw_imm:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 31
+; RV64XANDESPERF-NEXT:    addi a0, a0, 11
+; RV64XANDESPERF-NEXT:    ret
   %a = zext i32 %0 to i64
   %b = shl i64 %a, 1
   %c = add i64 %b, 11
@@ -1150,6 +1522,13 @@
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 2
 ; RV64ZBA-NEXT:    addi a0, a0, -12
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh2adduw_imm:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 30
+; RV64XANDESPERF-NEXT:    addi a0, a0, -12
+; RV64XANDESPERF-NEXT:    ret
   %a = zext i32 %0 to i64
   %b = shl i64 %a, 2
   %c = add i64 %b, -12
@@ -1169,6 +1548,13 @@
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
 ; RV64ZBA-NEXT:    addi a0, a0, 13
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh3adduw_imm:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 29
+; RV64XANDESPERF-NEXT:    addi a0, a0, 13
+; RV64XANDESPERF-NEXT:    ret
   %a = zext i32 %0 to i64
   %b = shl i64 %a, 3
   %c = add i64 %b, 13
@@ -1188,6 +1574,12 @@
 ; RV64ZBA-NEXT:    zext.w a0, a0
 ; RV64ZBA-NEXT:    addi a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: adduw_imm:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, zero, a0
+; RV64XANDESPERF-NEXT:    addi a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %a = zext i32 %0 to i64
   %b = add i64 %a, 5
   ret i64 %b
@@ -1206,6 +1598,12 @@
 ; RV64ZBA-NEXT:    slli a1, a0, 8
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul258:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a0, 8
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 258
   ret i64 %c
 }
@@ -1223,6 +1621,12 @@
 ; RV64ZBA-NEXT:    slli a1, a0, 8
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul260:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a0, 8
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 260
   ret i64 %c
 }
@@ -1240,6 +1644,12 @@
 ; RV64ZBA-NEXT:    slli a1, a0, 8
 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul264:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a0, 8
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 264
   ret i64 %c
 }
@@ -1257,6 +1667,13 @@
 ; RV64ZBA-NEXT:    li a0, -2
 ; RV64ZBA-NEXT:    zext.w a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: imm_zextw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    li a0, 1
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    addi a0, a0, -2
+; RV64XANDESPERF-NEXT:    ret
   ret i64 4294967294 ; -2 in 32 bits.
 }
 
@@ -1272,6 +1689,12 @@
 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul11:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 11
   ret i64 %c
 }
@@ -1288,6 +1711,12 @@
 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul19:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 19
   ret i64 %c
 }
@@ -1304,6 +1733,12 @@
 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul13:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a1, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 13
   ret i64 %c
 }
@@ -1320,6 +1755,12 @@
 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul21:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 21
   ret i64 %c
 }
@@ -1336,6 +1777,12 @@
 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul37:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 37
   ret i64 %c
 }
@@ -1352,6 +1799,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul25:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 25
   ret i64 %c
 }
@@ -1368,6 +1821,12 @@
 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul41:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a1, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 41
   ret i64 %c
 }
@@ -1384,6 +1843,12 @@
 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul73:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a1, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 73
   ret i64 %c
 }
@@ -1400,6 +1865,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul27:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 27
   ret i64 %c
 }
@@ -1416,6 +1887,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul45:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 45
   ret i64 %c
 }
@@ -1432,6 +1909,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul81:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 81
   ret i64 %c
 }
@@ -1449,6 +1932,12 @@
 ; RV64ZBA-NEXT:    slli a1, a0, 12
 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul4098:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a0, 12
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 4098
   ret i64 %c
 }
@@ -1466,6 +1955,12 @@
 ; RV64ZBA-NEXT:    slli a1, a0, 12
 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul4100:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a0, 12
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 4100
   ret i64 %c
 }
@@ -1483,6 +1978,12 @@
 ; RV64ZBA-NEXT:    slli a1, a0, 12
 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul4104:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a0, 12
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, 4104
   ret i64 %c
 }
@@ -1500,6 +2001,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    slliw a0, a0, 6
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mulw192:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    slliw a0, a0, 6
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 192
   ret i32 %c
 }
@@ -1517,6 +2024,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    slliw a0, a0, 6
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mulw320:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    slliw a0, a0, 6
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 320
   ret i32 %c
 }
@@ -1534,6 +2047,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
 ; RV64ZBA-NEXT:    slliw a0, a0, 6
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mulw576:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    slliw a0, a0, 6
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i32 %a, 576
   ret i32 %c
 }
@@ -1551,6 +2070,12 @@
 ; RV64ZBA-NEXT:    li a1, 1026
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: add4104:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    li a1, 1026
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = add i64 %a, 4104
   ret i64 %c
 }
@@ -1568,6 +2093,12 @@
 ; RV64ZBA-NEXT:    li a1, 1026
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: add4104_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    li a1, 1026
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = or disjoint i64 %a, 4104
   ret i64 %c
 }
@@ -1585,6 +2116,12 @@
 ; RV64ZBA-NEXT:    li a1, 1026
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: add8208:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    li a1, 1026
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %c = add i64 %a, 8208
   ret i64 %c
 }
@@ -1624,6 +2161,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    slliw a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addshl32_5_6:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV64XANDESPERF-NEXT:    slliw a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = shl i32 %a, 5
   %d = shl i32 %b, 6
   %e = add i32 %c, %d
@@ -1643,6 +2186,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addshl64_5_6:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV64XANDESPERF-NEXT:    slli a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = shl i64 %a, 5
   %d = shl i64 %b, 6
   %e = add i64 %c, %d
@@ -1662,6 +2211,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    slliw a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addshl32_5_7:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    slliw a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = shl i32 %a, 5
   %d = shl i32 %b, 7
   %e = add i32 %c, %d
@@ -1681,6 +2236,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addshl64_5_7:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    slli a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = shl i64 %a, 5
   %d = shl i64 %b, 7
   %e = add i64 %c, %d
@@ -1700,6 +2261,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    slliw a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addshl32_5_8:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    slliw a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = shl i32 %a, 5
   %d = shl i32 %b, 8
   %e = add i32 %c, %d
@@ -1719,6 +2286,12 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    slli a0, a0, 5
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: addshl64_5_8:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    slli a0, a0, 5
+; RV64XANDESPERF-NEXT:    ret
   %c = shl i64 %a, 5
   %d = shl i64 %b, 8
   %e = add i64 %c, %d
@@ -1747,6 +2320,13 @@
 ; RV64ZBAZBB-NEXT:    slli a0, a0, 23
 ; RV64ZBAZBB-NEXT:    srli a0, a0, 32
 ; RV64ZBAZBB-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sext_ashr_zext_i8:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 56
+; RV64XANDESPERF-NEXT:    srai a0, a0, 31
+; RV64XANDESPERF-NEXT:    srli a0, a0, 32
+; RV64XANDESPERF-NEXT:    ret
   %ext = sext i8 %a to i32
   %1 = ashr i32 %ext, 9
   ret i32 %1
@@ -1766,6 +2346,12 @@
 ; RV64ZBA-NEXT:    sh3add a1, a1, a2
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh6_sh3_add1:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    nds.lea.d a1, a2, a1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %shl = shl i64 %z, 3
   %shl1 = shl i64 %y, 6
@@ -1788,6 +2374,13 @@
 ; RV64ZBA-NEXT:    sh3add a1, a1, a2
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh6_sh3_add2:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    slli a1, a1, 6
+; RV64XANDESPERF-NEXT:    add a0, a1, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a2
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %shl = shl i64 %z, 3
   %shl1 = shl i64 %y, 6
@@ -1810,6 +2403,12 @@
 ; RV64ZBA-NEXT:    sh3add a1, a1, a2
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh6_sh3_add3:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    nds.lea.d a1, a2, a1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %shl = shl i64 %z, 3
   %shl1 = shl i64 %y, 6
@@ -1833,6 +2432,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a2, a0
 ; RV64ZBA-NEXT:    add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh6_sh3_add4:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    slli a1, a1, 6
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a2
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %shl = shl i64 %z, 3
   %shl1 = shl i64 %y, 6
@@ -1863,6 +2469,13 @@
 ; RV64ZBAZBB-NEXT:    slli a0, a0, 23
 ; RV64ZBAZBB-NEXT:    srli a0, a0, 32
 ; RV64ZBAZBB-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sext_ashr_zext_i16:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a0, a0, 48
+; RV64XANDESPERF-NEXT:    srai a0, a0, 25
+; RV64XANDESPERF-NEXT:    srli a0, a0, 32
+; RV64XANDESPERF-NEXT:    ret
   %ext = sext i16 %a to i32
   %1 = ashr i32 %ext, 9
   ret i32 %1
@@ -1887,6 +2500,13 @@
 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh1adduw_ptrdiff:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a0, a0, 1
+; RV64XANDESPERF-NEXT:    nds.lea.h.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %ptrdiff = lshr exact i64 %diff, 1
   %cast = and i64 %ptrdiff, 4294967295
   %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
@@ -1911,6 +2531,13 @@
 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh2adduw_ptrdiff:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a0, a0, 2
+; RV64XANDESPERF-NEXT:    nds.lea.w.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %ptrdiff = lshr exact i64 %diff, 2
   %cast = and i64 %ptrdiff, 4294967295
   %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
@@ -1935,6 +2562,13 @@
 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: sh3adduw_ptrdiff:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a0, a0, 3
+; RV64XANDESPERF-NEXT:    nds.lea.d.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %ptrdiff = lshr exact i64 %diff, 3
   %cast = and i64 %ptrdiff, 4294967295
   %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
@@ -1957,6 +2591,13 @@
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_1_sh1add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 1
+; RV64XANDESPERF-NEXT:    nds.lea.h.ze a0, a0, a1
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 1
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i16, ptr %0, i64 %4
@@ -1984,6 +2625,17 @@
 ; RV64ZBA-NEXT:    ld a0, 0(a1)
 ; RV64ZBA-NEXT:    ld a1, 8(a1)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: slliuw_ptrdiff:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    li a2, 1
+; RV64XANDESPERF-NEXT:    slli a2, a2, 36
+; RV64XANDESPERF-NEXT:    addi a2, a2, -16
+; RV64XANDESPERF-NEXT:    and a0, a0, a2
+; RV64XANDESPERF-NEXT:    add a1, a1, a0
+; RV64XANDESPERF-NEXT:    ld a0, 0(a1)
+; RV64XANDESPERF-NEXT:    ld a1, 8(a1)
+; RV64XANDESPERF-NEXT:    ret
   %ptrdiff = lshr exact i64 %diff, 4
   %cast = and i64 %ptrdiff, 4294967295
   %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
@@ -2006,6 +2658,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_2_sh2add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 2
+; RV64XANDESPERF-NEXT:    nds.lea.w.ze a0, a0, a1
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 2
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i32, ptr %0, i64 %4
@@ -2025,9 +2684,16 @@
 ; RV64ZBA-LABEL: srliw_3_sh3add:
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    srliw a1, a1, 3
-; RV64ZBA-NEXT:    sh3add a0, a1, a0
+; RV64ZBA-NEXT:    sh3add.uw a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_3_sh3add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 3
+; RV64XANDESPERF-NEXT:    nds.lea.d.ze a0, a0, a1
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 3
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i64, ptr %0, i64 %4
@@ -2050,6 +2716,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_1_sh2add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 1
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 1
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i32, ptr %0, i64 %4
@@ -2072,6 +2745,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_1_sh3add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 1
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i64, ptr %0, i64 %4
@@ -2094,6 +2774,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_2_sh3add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 2
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 2
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i64, ptr %0, i64 %4
@@ -2116,6 +2803,13 @@
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_2_sh1add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 2
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 2
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i16, ptr %0, i64 %4
@@ -2139,6 +2833,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_3_sh2add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 3
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 3
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i32, ptr %0, i64 %4
@@ -2161,6 +2862,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srliw_4_sh3add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a1, a1, 4
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i32 %1, 4
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i64, ptr %0, i64 %4
@@ -2183,6 +2891,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_1_sh2add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a1, a1, 1
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i64 %1, 1
   %4 = getelementptr inbounds i32, ptr %0, i64 %3
   %5 = load i32, ptr %4, align 4
@@ -2204,6 +2919,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_2_sh3add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a1, a1, 2
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i64 %1, 2
   %4 = getelementptr inbounds i64, ptr %0, i64 %3
   %5 = load i64, ptr %4, align 8
@@ -2225,6 +2947,13 @@
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_2_sh1add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a1, a1, 2
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i64 %1, 2
   %4 = getelementptr inbounds i16, ptr %0, i64 %3
   %5 = load i16, ptr %4, align 2
@@ -2246,6 +2975,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_3_sh2add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a1, a1, 3
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i64 %1, 3
   %4 = getelementptr inbounds i32, ptr %0, i64 %3
   %5 = load i32, ptr %4, align 4
@@ -2267,6 +3003,13 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_4_sh3add:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a1, a1, 4
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = lshr i64 %1, 4
   %4 = getelementptr inbounds i64, ptr %0, i64 %3
   %5 = load i64, ptr %4, align 8
@@ -2288,6 +3031,13 @@
 ; RV64ZBA-NEXT:    sh1add.uw a0, a1, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: shl_2_sh1adduw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 2
+; RV64XANDESPERF-NEXT:    nds.lea.h.ze a0, a0, a1
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i32 %1, 2
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i16, ptr %0, i64 %4
@@ -2310,6 +3060,13 @@
 ; RV64ZBA-NEXT:    sh2add.uw a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: shl_16_sh2adduw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 16
+; RV64XANDESPERF-NEXT:    nds.lea.w.ze a0, a0, a1
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i32 %1, 16
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i32, ptr %0, i64 %4
@@ -2332,6 +3089,13 @@
 ; RV64ZBA-NEXT:    sh3add.uw a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: shl_31_sh3adduw:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 31
+; RV64XANDESPERF-NEXT:    nds.lea.d.ze a0, a0, a1
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %3 = shl i32 %1, 31
   %4 = zext i32 %3 to i64
   %5 = getelementptr inbounds i64, ptr %0, i64 %4
@@ -2353,6 +3117,12 @@
 ; RV64ZBA-NEXT:    slli a1, a1, 32
 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: pack_i64:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 32
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %shl = and i64 %a, 4294967295
   %shl1 = shl i64 %b, 32
   %or = or i64 %shl1, %shl
@@ -2373,6 +3143,12 @@
 ; RV64ZBA-NEXT:    slli a1, a1, 32
 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: pack_i64_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 32
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %zexta = zext i32 %a to i64
   %zextb = zext i32 %b to i64
   %shl1 = shl i64 %zextb, 32
@@ -2392,6 +3168,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: pack_i64_disjoint:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %shl = and i64 %a, 4294967295
   %or = or disjoint i64 %b, %shl
   ret i64 %or
@@ -2409,6 +3190,11 @@
 ; RV64ZBA:       # %bb.0:
 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: pack_i64_disjoint_2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.b.ze a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
   %zexta = zext i32 %a to i64
   %or = or disjoint i64 %b, %zexta
   ret i64 %or
@@ -2429,6 +3215,13 @@
 ; RV64ZBA-NEXT:    add a0, a0, a2
 ; RV64ZBA-NEXT:    lbu a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh1_sh0:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a1
+; RV64XANDESPERF-NEXT:    add a0, a0, a2
+; RV64XANDESPERF-NEXT:    lbu a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [2 x i8], ptr %p, i64 %idx1, i64 %idx2
   %b = load i8, ptr %a, align 1
   ret i8 %b
@@ -2450,6 +3243,13 @@
 ; RV64ZBA-NEXT:    sh1add a0, a2, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh1_sh1:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a2
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [2 x i16], ptr %p, i64 %idx1, i64 %idx2
   %b = load i16, ptr %a, align 2
   ret i16 %b
@@ -2471,6 +3271,13 @@
 ; RV64ZBA-NEXT:    sh2add a0, a2, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh1_sh2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a2
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [2 x i32], ptr %p, i64 %idx1, i64 %idx2
   %b = load i32, ptr %a, align 4
   ret i32 %b
@@ -2492,6 +3299,14 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh1_sh3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 4
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a2
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [2 x i64], ptr %p, i64 %idx1, i64 %idx2
   %b = load i64, ptr %a, align 8
   ret i64 %b
@@ -2512,6 +3327,13 @@
 ; RV64ZBA-NEXT:    add a0, a0, a2
 ; RV64ZBA-NEXT:    lbu a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh2_sh0:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a1
+; RV64XANDESPERF-NEXT:    add a0, a0, a2
+; RV64XANDESPERF-NEXT:    lbu a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [4 x i8], ptr %p, i64 %idx1, i64 %idx2
   %b = load i8, ptr %a, align 1
   ret i8 %b
@@ -2533,6 +3355,13 @@
 ; RV64ZBA-NEXT:    sh1add a0, a2, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh2_sh1:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a2
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [4 x i16], ptr %p, i64 %idx1, i64 %idx2
   %b = load i16, ptr %a, align 2
   ret i16 %b
@@ -2554,6 +3383,14 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh2_sh2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 4
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a2
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [4 x i32], ptr %p, i64 %idx1, i64 %idx2
   %b = load i32, ptr %a, align 4
   ret i32 %b
@@ -2575,6 +3412,14 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh2_sh3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 5
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a2
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [4 x i64], ptr %p, i64 %idx1, i64 %idx2
   %b = load i64, ptr %a, align 8
   ret i64 %b
@@ -2595,6 +3440,13 @@
 ; RV64ZBA-NEXT:    add a0, a0, a2
 ; RV64ZBA-NEXT:    lbu a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh3_sh0:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    add a0, a0, a2
+; RV64XANDESPERF-NEXT:    lbu a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [8 x i8], ptr %p, i64 %idx1, i64 %idx2
   %b = load i8, ptr %a, align 1
   ret i8 %b
@@ -2616,6 +3468,14 @@
 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh3_sh1:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 4
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a2
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [8 x i16], ptr %p, i64 %idx1, i64 %idx2
   %b = load i16, ptr %a, align 2
   ret i16 %b
@@ -2637,6 +3497,14 @@
 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh3_sh2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 5
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a2
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [8 x i32], ptr %p, i64 %idx1, i64 %idx2
   %b = load i32, ptr %a, align 4
   ret i32 %b
@@ -2658,6 +3526,14 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh3_sh3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 6
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a2
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [8 x i64], ptr %p, i64 %idx1, i64 %idx2
   %b = load i64, ptr %a, align 8
   ret i64 %b
@@ -2683,6 +3559,15 @@
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_lshr_sh3_sh3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srli a1, a1, 58
+; RV64XANDESPERF-NEXT:    slli a1, a1, 6
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a2
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %shr = lshr i64 %idx1, 58
   %a = getelementptr inbounds [8 x i64], ptr %p, i64 %shr, i64 %idx2
   %b = load i64, ptr %a, align 8
@@ -2719,6 +3604,14 @@
 ; RV64ZBA-NEXT:    sh1add a0, a2, a0
 ; RV64ZBA-NEXT:    lh a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh4_sh1:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 5
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a2
+; RV64XANDESPERF-NEXT:    lh a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [16 x i16], ptr %p, i64 %idx1, i64 %idx2
   %b = load i16, ptr %a, align 2
   ret i16 %b
@@ -2741,6 +3634,14 @@
 ; RV64ZBA-NEXT:    sh2add a0, a2, a0
 ; RV64ZBA-NEXT:    lw a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh4_sh2:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 6
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a2
+; RV64XANDESPERF-NEXT:    lw a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [16 x i32], ptr %p, i64 %idx1, i64 %idx2
   %b = load i32, ptr %a, align 4
   ret i32 %b
@@ -2763,6 +3664,14 @@
 ; RV64ZBA-NEXT:    sh3add a0, a2, a0
 ; RV64ZBA-NEXT:    ld a0, 0(a0)
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: array_index_sh4_sh3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    slli a1, a1, 7
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a2
+; RV64XANDESPERF-NEXT:    ld a0, 0(a0)
+; RV64XANDESPERF-NEXT:    ret
   %a = getelementptr inbounds [16 x i64], ptr %p, i64 %idx1, i64 %idx2
   %b = load i64, ptr %a, align 8
   ret i64 %b
@@ -2784,6 +3693,14 @@
 ; RV64ZBA-NEXT:    add a1, a2, a1
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: test_gep_gep_dont_crash:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    srliw a2, a2, 6
+; RV64XANDESPERF-NEXT:    slli a2, a2, 3
+; RV64XANDESPERF-NEXT:    add a0, a0, a2
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
   %lshr = lshr i64 %a2, 6
   %and = and i64 %lshr, 67108863
   %gep1 = getelementptr i64, ptr %p, i64 %and
@@ -2807,6 +3724,14 @@
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: regression:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    subw a0, a0, a1
+; RV64XANDESPERF-NEXT:    slli a0, a0, 32
+; RV64XANDESPERF-NEXT:    srli a0, a0, 29
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %sub = sub i32 %x, %y
   %ext = zext i32 %sub to i64
   %res = mul nuw nsw i64 %ext, 24
@@ -2845,6 +3770,12 @@
 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
 ; RV64ZBA-NEXT:    neg a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul_neg3:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    neg a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, -3
   ret i64 %c
 }
@@ -2872,6 +3803,12 @@
 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
 ; RV64ZBA-NEXT:    neg a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: mul_neg5:
+; RV64XANDESPERF:       # %bb.0:
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    neg a0, a0
+; RV64XANDESPERF-NEXT:    ret
   %c = mul i64 %a, -5
   ret i64 %c
 }
@@ -2938,6 +3875,14 @@
 ; RV64ZBAZBBZBS-NEXT:    sh1add a0, a0, a0
 ; RV64ZBAZBBZBS-NEXT:    slli a0, a0, 2
 ; RV64ZBAZBBZBS-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: bext_mul12:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    srlw a0, a0, a1
+; RV64XANDESPERF-NEXT:    andi a0, a0, 1
+; RV64XANDESPERF-NEXT:    nds.lea.h a0, a0, a0
+; RV64XANDESPERF-NEXT:    slli a0, a0, 2
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %3 = lshr i32 %1, %2
   %4 = and i32 %3, 1
@@ -2977,6 +3922,14 @@
 ; RV64ZBAZBBZBS-NEXT:    sh2add a0, a0, a0
 ; RV64ZBAZBBZBS-NEXT:    sh3add a0, a0, a0
 ; RV64ZBAZBBZBS-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: bext_mul45:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    srlw a0, a0, a1
+; RV64XANDESPERF-NEXT:    andi a0, a0, 1
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a0, a0
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a0
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %3 = lshr i32 %1, %2
   %4 = and i32 %3, 1
@@ -3017,6 +3970,14 @@
 ; RV64ZBAZBBZBS-NEXT:    slli a1, a0, 7
 ; RV64ZBAZBBZBS-NEXT:    sh2add a0, a0, a1
 ; RV64ZBAZBBZBS-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: bext_mul132:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    srlw a0, a0, a1
+; RV64XANDESPERF-NEXT:    andi a0, a0, 1
+; RV64XANDESPERF-NEXT:    slli a1, a0, 7
+; RV64XANDESPERF-NEXT:    nds.lea.w a0, a1, a0
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %3 = lshr i32 %1, %2
   %4 = and i32 %3, 1
@@ -3043,6 +4004,17 @@
 ; RV64ZBA-NEXT:    sh2add a1, a1, a1
 ; RV64ZBA-NEXT:    add a0, a0, a1
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: gep_lshr_i32:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    slli a1, a1, 2
+; RV64XANDESPERF-NEXT:    li a2, 1
+; RV64XANDESPERF-NEXT:    slli a2, a2, 36
+; RV64XANDESPERF-NEXT:    addi a2, a2, -16
+; RV64XANDESPERF-NEXT:    and a1, a1, a2
+; RV64XANDESPERF-NEXT:    nds.lea.w a1, a1, a1
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %2 = lshr exact i64 %1, 2
   %3 = and i64 %2, 4294967295
@@ -3065,6 +4037,15 @@
 ; RV64ZBA-NEXT:    srli a0, a0, 2
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 4
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_slliuw:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    slli a0, a0, 2
+; RV64XANDESPERF-NEXT:    li a1, 1
+; RV64XANDESPERF-NEXT:    slli a1, a1, 36
+; RV64XANDESPERF-NEXT:    addi a1, a1, -16
+; RV64XANDESPERF-NEXT:    and a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %2 = lshr exact i64 %1, 2
   %3 = and i64 %2, 4294967295
@@ -3087,6 +4068,15 @@
 ; RV64ZBA-NEXT:    srli a0, a0, 2
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 4
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_slliuw_canonical:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    slli a0, a0, 2
+; RV64XANDESPERF-NEXT:    li a1, 1
+; RV64XANDESPERF-NEXT:    slli a1, a1, 36
+; RV64XANDESPERF-NEXT:    addi a1, a1, -16
+; RV64XANDESPERF-NEXT:    and a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %1 = shl i64 %0, 2
   %2 = and i64 %1, 68719476720
@@ -3136,6 +4126,15 @@
 ; RV64ZBA-NEXT:    srli a0, a0, 18
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_slliuw_2:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    srli a0, a0, 15
+; RV64XANDESPERF-NEXT:    li a1, 1
+; RV64XANDESPERF-NEXT:    slli a1, a1, 35
+; RV64XANDESPERF-NEXT:    addi a1, a1, -8
+; RV64XANDESPERF-NEXT:    and a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %2 = lshr i64 %1, 18
   %3 = and i64 %2, 4294967295
@@ -3158,6 +4157,15 @@
 ; RV64ZBA-NEXT:    srli a0, a0, 18
 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srli_slliuw_canonical_2:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    srli a0, a0, 15
+; RV64XANDESPERF-NEXT:    li a1, 1
+; RV64XANDESPERF-NEXT:    slli a1, a1, 35
+; RV64XANDESPERF-NEXT:    addi a1, a1, -8
+; RV64XANDESPERF-NEXT:    and a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %1 = lshr i64 %0, 15
   %2 = and i64 %1, 34359738360
@@ -3179,6 +4187,13 @@
 ; RV64ZBA-NEXT:    srli a1, a1, 6
 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: srai_srli_sh3add:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    srai a1, a1, 32
+; RV64XANDESPERF-NEXT:    srli a1, a1, 6
+; RV64XANDESPERF-NEXT:    nds.lea.d a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %2 = ashr i64 %1, 32
   %3 = lshr i64 %2, 6
@@ -3246,6 +4261,16 @@
 ; RV64ZBA-NEXT:    addi a0, a0, -2
 ; RV64ZBA-NEXT:    zext.w a0, a0
 ; RV64ZBA-NEXT:    ret
+;
+; RV64XANDESPERF-LABEL: add_u32simm32_zextw:
+; RV64XANDESPERF:       # %bb.0: # %entry
+; RV64XANDESPERF-NEXT:    li a1, 1
+; RV64XANDESPERF-NEXT:    slli a1, a1, 32
+; RV64XANDESPERF-NEXT:    addi a1, a1, -2
+; RV64XANDESPERF-NEXT:    add a0, a0, a1
+; RV64XANDESPERF-NEXT:    addi a1, a1, 1
+; RV64XANDESPERF-NEXT:    and a0, a0, a1
+; RV64XANDESPERF-NEXT:    ret
 entry:
   %add = add i64 %x, 4294967294
   %and = and i64 %add, 4294967295