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
