llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Pengcheng Wang (wangpc-pp)

<details>
<summary>Changes</summary>

Thanks for `XTheadMemidx` extension that makes life easier.


---

Patch is 35.74 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/209420.diff


5 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp (+12-7) 
- (modified) llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h (+31-4) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td (+103) 
- (modified) llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp (+9) 
- (added) llvm/test/CodeGen/RISCV/zilx.ll (+970) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp 
b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index c86926e075c99..9208762e8d1fe 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -3736,7 +3736,8 @@ static bool isRegRegScaleLoadOrStore(SDNode *User, 
SDValue Add,
     return false;
   EVT VT = cast<MemSDNode>(User)->getMemoryVT();
   if (!(VT.isScalarInteger() &&
-        (Subtarget.hasVendorXTHeadMemIdx() || Subtarget.hasVendorXqcisls())) &&
+        (Subtarget.hasStdExtZilx() ||
+         Subtarget.hasVendorXTHeadMemIdx() || Subtarget.hasVendorXqcisls())) &&
       !((VT == MVT::f32 || VT == MVT::f64) &&
         Subtarget.hasVendorXTHeadFMemIdx()))
     return false;
@@ -3785,7 +3786,7 @@ static bool isWorthFoldingIntoRegRegScale(const 
RISCVSubtarget &Subtarget,
 }
 
 bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue Addr,
-                                              unsigned MaxShiftAmount,
+                                              ArrayRef<unsigned> Amounts,
                                               SDValue &Base, SDValue &Index,
                                               SDValue &Scale) {
   if (Addr.getOpcode() != ISD::ADD)
@@ -3794,14 +3795,14 @@ bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue 
Addr,
   SDValue RHS = Addr.getOperand(1);
 
   EVT VT = Addr.getSimpleValueType();
-  auto SelectShl = [this, VT, MaxShiftAmount](SDValue N, SDValue &Index,
-                                              SDValue &Shift) {
+  auto SelectShl = [this, VT, Amounts](SDValue N, SDValue &Index,
+                                       SDValue &Shift) {
     if (N.getOpcode() != ISD::SHL || !isa<ConstantSDNode>(N.getOperand(1)))
       return false;
 
     // Only match shifts by a value in range [0, MaxShiftAmount].
     unsigned ShiftAmt = N.getConstantOperandVal(1);
-    if (ShiftAmt > MaxShiftAmount)
+    if (!llvm::is_contained(Amounts, ShiftAmt))
       return false;
 
     Index = N.getOperand(0);
@@ -3861,6 +3862,10 @@ bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue 
Addr,
   if (!isWorthFoldingIntoRegRegScale(*Subtarget, Addr))
     return false;
 
+  // Bail out if 0 is not in candicate shift amounts.
+  if (!llvm::is_contained(Amounts, 0))
+    return false;
+
   Base = LHS;
   Index = RHS;
   Scale = CurDAG->getTargetConstant(0, SDLoc(Addr), VT);
@@ -3868,11 +3873,11 @@ bool RISCVDAGToDAGISel::SelectAddrRegRegScale(SDValue 
Addr,
 }
 
 bool RISCVDAGToDAGISel::SelectAddrRegZextRegScale(SDValue Addr,
-                                                  unsigned MaxShiftAmount,
+                                                  ArrayRef<unsigned> Amounts,
                                                   unsigned Bits, SDValue &Base,
                                                   SDValue &Index,
                                                   SDValue &Scale) {
-  if (!SelectAddrRegRegScale(Addr, MaxShiftAmount, Base, Index, Scale))
+  if (!SelectAddrRegRegScale(Addr, Amounts, Base, Index, Scale))
     return false;
 
   if (Index.getOpcode() == ISD::AND) {
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h 
b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 190dc083d014a..41938f76397eb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -53,23 +53,50 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
   bool SelectAddrRegImm9(SDValue Addr, SDValue &Base, SDValue &Offset);
   bool SelectAddrRegImmLsb00000(SDValue Addr, SDValue &Base, SDValue &Offset);
 
-  bool SelectAddrRegRegScale(SDValue Addr, unsigned MaxShiftAmount,
+  bool SelectAddrRegRegScale(SDValue Addr, ArrayRef<unsigned> Amounts,
                              SDValue &Base, SDValue &Index, SDValue &Scale);
 
+  template <unsigned ShiftAmount>
+  bool SelectAddrRegRegFixedScale(SDValue Addr, SDValue &Base, SDValue &Index) 
{
+    SDValue Scale;
+    if (!SelectAddrRegRegScale(Addr, ShiftAmount, Base, Index, Scale))
+      return false;
+    assert(Scale->getAsZExtVal() == ShiftAmount &&
+           "ShiftAmount doesn't match!");
+    return true;
+  }
+
   template <unsigned MaxShift>
   bool SelectAddrRegRegScale(SDValue Addr, SDValue &Base, SDValue &Index,
                              SDValue &Scale) {
-    return SelectAddrRegRegScale(Addr, MaxShift, Base, Index, Scale);
+    SmallVector<unsigned, MaxShift> Amounts;
+    for (unsigned I = 0; I <= MaxShift; I++)
+      Amounts.push_back(I);
+    return SelectAddrRegRegScale(Addr, Amounts, Base, Index, Scale);
   }
 
-  bool SelectAddrRegZextRegScale(SDValue Addr, unsigned MaxShiftAmount,
+  bool SelectAddrRegZextRegScale(SDValue Addr, ArrayRef<unsigned> Amounts,
                                  unsigned Bits, SDValue &Base, SDValue &Index,
                                  SDValue &Scale);
 
+  template <unsigned ShiftAmount, unsigned Bits>
+  bool SelectAddrRegZextRegFixedScale(SDValue Addr, SDValue &Base,
+                                      SDValue &Index) {
+    SDValue Scale;
+    if (!SelectAddrRegZextRegScale(Addr, ShiftAmount, Bits, Base, Index, 
Scale))
+      return false;
+    assert(Scale->getAsZExtVal() == ShiftAmount &&
+           "ShiftAmount doesn't match!");
+    return true;
+  }
+
   template <unsigned MaxShift, unsigned Bits>
   bool SelectAddrRegZextRegScale(SDValue Addr, SDValue &Base, SDValue &Index,
                                  SDValue &Scale) {
-    return SelectAddrRegZextRegScale(Addr, MaxShift, Bits, Base, Index, Scale);
+    SmallVector<unsigned, MaxShift> Amounts;
+    for (unsigned I = 0; I <= MaxShift; I++)
+      Amounts.push_back(I);
+    return SelectAddrRegZextRegScale(Addr, Amounts, Bits, Base, Index, Scale);
   }
 
   bool SelectAddrRegReg(SDValue Addr, SDValue &Base, SDValue &Offset);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
index 2c43e4e30eb31..8cd56ddee4846 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZilx.td
@@ -71,3 +71,106 @@ def LXWU_S_UW : ScaledIndexLoad<0b101, 0b10, 1, 
"lxwu.s.uw">, Sched<[WriteLDW, R
 def LXD_S     : ScaledIndexLoad<0b100, 0b11, 0, "lxd.s">, Sched<[WriteLDD, 
ReadMemBase, ReadMemBase]>;
 def LXD_S_UW  : ScaledIndexLoad<0b101, 0b11, 0, "lxd.s.uw">, Sched<[WriteLDD, 
ReadMemBase, ReadMemBase]>;
 } // Predicates = [HasStdExtZilsx, IsRV64]
+
+class AddrRegReg<int N>
+    : ComplexPattern<iPTR, 2, "SelectAddrRegRegFixedScale<"#N#">">;
+class AddrRegZextReg<int N>
+    : ComplexPattern<i64, 2, "SelectAddrRegZextRegFixedScale<"#N#", 32>",
+                     [], [], 10>;
+
+def AddrRegReg0 : AddrRegReg<0>;
+def AddrRegReg1 : AddrRegReg<1>;
+def AddrRegReg2 : AddrRegReg<2>;
+def AddrRegReg3 : AddrRegReg<3>;
+
+def AddrRegZextReg0 : AddrRegZextReg<0>;
+def AddrRegZextReg1 : AddrRegZextReg<1>;
+def AddrRegZextReg2 : AddrRegZextReg<2>;
+def AddrRegZextReg3 : AddrRegZextReg<3>;
+
+let AddedComplexity = 2 in {
+class UnscaledIndexLoadPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT>
+    : Pat<(vt (LoadOp (AddrRegReg0 (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)))),
+          (Inst GPR:$rs1, GPR:$rs2)>;
+} // AddedComplexity = 2
+
+let AddedComplexity = 3 in {
+class UnscaledZextIndexLoadPat<PatFrag LoadOp, RVInst Inst, ValueType vt = 
XLenVT>
+    : Pat<(vt (LoadOp (AddrRegZextReg0 (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)))),
+          (Inst GPR:$rs1, GPR:$rs2)>;
+} // AddedComplexity = 3
+
+let AddedComplexity = 4 in {
+class ScaledIndexLoadPat<PatFrag LoadOp, RVInst Inst, int Scale, ValueType vt 
= XLenVT>
+    : Pat<(vt (LoadOp (!cast<AddrRegReg>("AddrRegReg" # Scale)
+                      (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)))),
+          (Inst GPR:$rs1, GPR:$rs2)>;
+} // AddedComplexity = 4
+
+let AddedComplexity = 6 in {
+class ScaledZextIndexLoadPat<PatFrag LoadOp, RVInst Inst, int Scale, ValueType 
vt = XLenVT>
+    : Pat<(vt (LoadOp (!cast<AddrRegZextReg>("AddrRegZextReg" # Scale)
+                      (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)))),
+          (Inst GPR:$rs1, GPR:$rs2)>;
+} // AddedComplexity = 6
+
+// Patterns
+let Predicates = [HasStdExtZilx] in {
+def : UnscaledIndexLoadPat<extloadi8, LXB>;
+def : UnscaledIndexLoadPat<sextloadi8, LXB>;
+def : UnscaledIndexLoadPat<zextloadi8, LXBU>;
+
+def : UnscaledIndexLoadPat<extloadi16, LXH>;
+def : UnscaledIndexLoadPat<sextloadi16, LXH>;
+def : UnscaledIndexLoadPat<zextloadi16, LXHU>;
+
+def : UnscaledIndexLoadPat<load, LXW, i32>;
+
+def : ScaledIndexLoadPat<extloadi16, LXH_S, 1>;
+def : ScaledIndexLoadPat<sextloadi16, LXH_S, 1>;
+def : ScaledIndexLoadPat<zextloadi16, LXHU_S, 1>;
+
+def : ScaledIndexLoadPat<load, LXW_S, 2, i32>;
+} // Predicates = [HasStdExtZilx]
+
+let Predicates = [HasStdExtZilx, IsRV64] in {
+def : UnscaledIndexLoadPat<extloadi32, LXW, i64>;
+def : UnscaledIndexLoadPat<sextloadi32, LXW, i64>;
+def : UnscaledIndexLoadPat<zextloadi32, LXWU, i64>;
+
+def : UnscaledIndexLoadPat<load, LXD, i64>;
+
+def : ScaledIndexLoadPat<extloadi32, LXW_S, 2, i64>;
+def : ScaledIndexLoadPat<sextloadi32, LXW_S, 2, i64>;
+def : ScaledIndexLoadPat<zextloadi32, LXWU_S, 2, i64>;
+
+def : ScaledIndexLoadPat<load, LXD_S, 3, i64>;
+
+def : UnscaledZextIndexLoadPat<extloadi8, LXB_UW>;
+def : UnscaledZextIndexLoadPat<sextloadi8, LXB_UW>;
+def : UnscaledZextIndexLoadPat<zextloadi8, LXBU_UW>;
+
+def : UnscaledZextIndexLoadPat<extloadi16, LXH_UW>;
+def : UnscaledZextIndexLoadPat<sextloadi16, LXH_UW>;
+def : UnscaledZextIndexLoadPat<zextloadi16, LXHU_UW>;
+
+def : UnscaledZextIndexLoadPat<load, LXW_UW, i32>;
+
+def : UnscaledZextIndexLoadPat<extloadi32, LXW_UW>;
+def : UnscaledZextIndexLoadPat<sextloadi32, LXW_UW>;
+def : UnscaledZextIndexLoadPat<zextloadi32, LXWU_UW>;
+
+def : UnscaledZextIndexLoadPat<load, LXD_UW>;
+
+def : ScaledZextIndexLoadPat<extloadi16, LXH_S_UW, 1>;
+def : ScaledZextIndexLoadPat<sextloadi16, LXH_S_UW, 1>;
+def : ScaledZextIndexLoadPat<zextloadi16, LXHU_S_UW, 1>;
+
+def : ScaledZextIndexLoadPat<load, LXW_S_UW, 2, i32>;
+
+def : ScaledZextIndexLoadPat<extloadi32, LXW_S_UW, 2, i64>;
+def : ScaledZextIndexLoadPat<sextloadi32, LXW_S_UW, 2, i64>;
+def : ScaledZextIndexLoadPat<zextloadi32, LXWU_S_UW, 2, i64>;
+
+def : ScaledZextIndexLoadPat<load, LXD_S_UW, 3, i64>;
+} // Predicates = [HasStdExtZilx, IsRV64]
diff --git a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp 
b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
index 1ad2956320b9d..01423fa11e66e 100644
--- a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
+++ b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp
@@ -689,6 +689,8 @@ static bool isSignExtendedW(Register SrcReg, const 
RISCVSubtarget &ST,
       [[fallthrough]];
     case RISCV::ADD:
     case RISCV::LWU:
+    case RISCV::LXD:
+    case RISCV::LXWU:
     case RISCV::MUL:
     case RISCV::SUB:
       if (hasAllWUsers(*MI, ST, MRI)) {
@@ -713,6 +715,9 @@ static unsigned getWOp(unsigned Opcode) {
   case RISCV::LD:
   case RISCV::LWU:
     return RISCV::LW;
+  case RISCV::LXD:
+  case RISCV::LXWU:
+    return RISCV::LXW;
   case RISCV::MUL:
     return RISCV::MULW;
   case RISCV::SLLI:
@@ -835,6 +840,10 @@ bool 
RISCVOptWInstrs::canonicalizeWSuffixes(MachineFunction &MF,
       case RISCV::LWU:
         WOpc = RISCV::LW;
         break;
+      case RISCV::LXD:
+      case RISCV::LXWU:
+        WOpc = RISCV::LXW;
+        break;
       }
 
       if (ShouldStripW && NonWOpc.has_value() && hasAllWUsers(MI, ST, MRI)) {
diff --git a/llvm/test/CodeGen/RISCV/zilx.ll b/llvm/test/CodeGen/RISCV/zilx.ll
new file mode 100644
index 0000000000000..3a27d801230a7
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/zilx.ll
@@ -0,0 +1,970 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV32 %s
+; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+experimental-zilx 
-verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV32-ZILX %s
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV64 %s
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+experimental-zilx 
-verify-machineinstrs \
+; RUN:   | FileCheck -check-prefix=RV64-ZILX %s
+
+;------------------------------------------------------------------------------
+; Unscaled Load
+;------------------------------------------------------------------------------
+
+define i8 @lxb_anyext(ptr %a, iXLen %b) {
+; RV32-LABEL: lxb_anyext:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lbu a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxb_anyext:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxb_anyext:
+; RV64:       # %bb.0:
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lbu a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxb_anyext:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxb a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i8, ptr %a, iXLen %b
+  %2 = load i8, ptr %1, align 1
+  ret i8 %2
+}
+
+define i32 @lxb(ptr %a, iXLen %b) {
+; RV32-LABEL: lxb:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lb a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxb:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxb:
+; RV64:       # %bb.0:
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lb a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxb:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxb a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i8, ptr %a, iXLen %b
+  %2 = load i8, ptr %1, align 1
+  %3 = sext i8 %2 to i32
+  ret i32 %3
+}
+
+define i8 @lxb_uw_anyext(ptr %a, i32 %b) {
+; RV32-LABEL: lxb_uw_anyext:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lbu a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxb_uw_anyext:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxb_uw_anyext:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 32
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lbu a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxb_uw_anyext:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxb.uw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i8, ptr %a, i64 %1
+  %3 = load i8, ptr %2, align 1
+  ret i8 %3
+}
+
+define i32 @lxb_uw(ptr %a, i32 %b) {
+; RV32-LABEL: lxb_uw:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lb a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxb_uw:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxb a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxb_uw:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 32
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lb a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxb_uw:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxb.uw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i8, ptr %a, i64 %1
+  %3 = load i8, ptr %2, align 1
+  %4 = sext i8 %3 to i32
+  ret i32 %4
+}
+
+define i32 @lxbu(ptr %a, iXLen %b) {
+; RV32-LABEL: lxbu:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lbu a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxbu:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxbu:
+; RV64:       # %bb.0:
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lbu a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxbu:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i8, ptr %a, iXLen %b
+  %2 = load i8, ptr %1, align 1
+  %3 = zext i8 %2 to i32
+  ret i32 %3
+}
+
+define i32 @lxbu_uw(ptr %a, i32 %b) {
+; RV32-LABEL: lxbu_uw:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lbu a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxbu_uw:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxbu a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxbu_uw:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 32
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lbu a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxbu_uw:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxbu.uw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i8, ptr %a, i64 %1
+  %3 = load i8, ptr %2, align 1
+  %4 = zext i8 %3 to i32
+  ret i32 %4
+}
+
+define i16 @lxh(ptr %a, iXLen %b) {
+; RV32-LABEL: lxh:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lh a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxh:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxh:
+; RV64:       # %bb.0:
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lh a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxh:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxh a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i8, ptr %a, iXLen %b
+  %2 = load i16, ptr %1, align 2
+  ret i16 %2
+}
+
+define i16 @lxh_uw(ptr %a, i32 %b) {
+; RV32-LABEL: lxh_uw:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lh a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxh_uw:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxh a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxh_uw:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 32
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lh a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxh_uw:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxh.uw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i8, ptr %a, i64 %1
+  %3 = load i16, ptr %2, align 2
+  ret i16 %3
+}
+
+define i32 @lxhu(ptr %a, iXLen %b) {
+; RV32-LABEL: lxhu:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lhu a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxhu:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxhu a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxhu:
+; RV64:       # %bb.0:
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lhu a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxhu:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxhu a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i8, ptr %a, iXLen %b
+  %2 = load i16, ptr %1, align 2
+  %3 = zext i16 %2 to i32
+  ret i32 %3
+}
+
+define i32 @lxhu_uw(ptr %a, i32 %b) {
+; RV32-LABEL: lxhu_uw:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lhu a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxhu_uw:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxhu a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxhu_uw:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a1, a1, 32
+; RV64-NEXT:    srli a1, a1, 32
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lhu a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxhu_uw:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxhu.uw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = zext i32 %b to i64
+  %2 = getelementptr i8, ptr %a, i64 %1
+  %3 = load i16, ptr %2, align 2
+  %4 = zext i16 %3 to i32
+  ret i32 %4
+}
+
+define i32 @lxw(ptr %a, iXLen %b) {
+; RV32-LABEL: lxw:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lw a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxw:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxw a0, (a0), a1
+; RV32-ZILX-NEXT:    ret
+;
+; RV64-LABEL: lxw:
+; RV64:       # %bb.0:
+; RV64-NEXT:    add a0, a0, a1
+; RV64-NEXT:    lw a0, 0(a0)
+; RV64-NEXT:    ret
+;
+; RV64-ZILX-LABEL: lxw:
+; RV64-ZILX:       # %bb.0:
+; RV64-ZILX-NEXT:    lxw a0, (a0), a1
+; RV64-ZILX-NEXT:    ret
+  %1 = getelementptr i8, ptr %a, iXLen %b
+  %2 = load i32, ptr %1, align 4
+  ret i32 %2
+}
+
+define i32 @lxw_uw(ptr %a, i32 %b) {
+; RV32-LABEL: lxw_uw:
+; RV32:       # %bb.0:
+; RV32-NEXT:    add a0, a0, a1
+; RV32-NEXT:    lw a0, 0(a0)
+; RV32-NEXT:    ret
+;
+; RV32-ZILX-LABEL: lxw_uw:
+; RV32-ZILX:       # %bb.0:
+; RV32-ZILX-NEXT:    lxw a0, (a0), a1
+; R...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/209420
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to