diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 52656134b7774..44a8245dc2a75 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -14,6 +14,14 @@ // Operand and SDNode transformation definitions. //===----------------------------------------------------------------------===// +def SDT_SetMultiple : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>, + SDTCisSameAs<1, 3>, + SDTCisPtrTy<2>, + SDTCisVT<3, XLenVT>]>; + +def qc_setwmi : RVSDNode<"QC_SETWMI", SDT_SetMultiple, + [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; + def uimm5nonzero : RISCVOp, ImmLeaf(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5, "NonZero">; @@ -27,6 +35,8 @@ def uimm5nonzero : RISCVOp, }]; } +def tuimm5nonzero : TImmLeaf(Imm);}]>; + def uimm5gt3 : RISCVOp, ImmLeaf 3) && isUInt<5>(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5, "GT3">; @@ -92,6 +102,8 @@ def uimm5slist : RISCVOp, ImmLeaf(Imm);}]>; + def uimm10 : RISCVUImmLeafOp<10>; def uimm11 : RISCVUImmLeafOp<11>; @@ -1566,6 +1578,11 @@ def : QCISELECTIICCPat ; def : QCISELECTIICCPat ; } // Predicates = [HasVendorXqcics, IsRV32] +let Predicates = [HasVendorXqcilsm, IsRV32] in { +def : Pat<(qc_setwmi GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7), + (QC_SETWMI GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7)>; +} // Predicates = [HasVendorXqcilsm, IsRV32] + //===----------------------------------------------------------------------===/i // Compress Instruction tablegen backend. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp index 6ecddad72c078..041dd07b48bf0 100644 --- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "RISCVSelectionDAGInfo.h" +#include "RISCVSubtarget.h" +#include "llvm/CodeGen/SelectionDAG.h" #define GET_SDNODE_DESC #include "RISCVGenSDNodeInfo.inc" @@ -62,3 +64,94 @@ void RISCVSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG, } #endif } + +SDValue RISCVSelectionDAGInfo::EmitTargetCodeForMemset( + SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline, + MachinePointerInfo DstPtrInfo) const { + const auto &Subtarget = DAG.getSubtarget(); + // We currently do this only for Xqcilsm + if (!Subtarget.hasVendorXqcilsm()) + return SDValue(); + + // Do this only if we know the size at compile time. + ConstantSDNode *ConstantSize = dyn_cast(Size); + if (!ConstantSize) + return SDValue(); + + uint64_t NumberOfBytesToWrite = ConstantSize->getZExtValue(); + + // Do this only if it is word aligned and we write a multiple of 4 bytes. + if (!(Alignment >= 4) || !((NumberOfBytesToWrite & 3) == 0)) + return SDValue(); + + SmallVector OutChains; + SDValue SrcValueReplicated = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Src); + int NumberOfWords = NumberOfBytesToWrite / 4; + MachineFunction &MF = DAG.getMachineFunction(); + auto Volatile = + isVolatile ? MachineMemOperand::MOVolatile : MachineMemOperand::MONone; + + // Helper for constructing the QC_SETWMI instruction + auto getSetwmiNode = [&](uint8_t SizeWords, uint8_t OffsetSetwmi) -> SDValue { + SDValue Ops[] = {Chain, SrcValueReplicated, Dst, + DAG.getTargetConstant(SizeWords, dl, MVT::i32), + DAG.getTargetConstant(OffsetSetwmi, dl, MVT::i32)}; + MachineMemOperand *BaseMemOperand = MF.getMachineMemOperand( + DstPtrInfo.getWithOffset(OffsetSetwmi), + MachineMemOperand::MOStore | Volatile, SizeWords * 4, Align(4)); + return DAG.getMemIntrinsicNode(RISCVISD::QC_SETWMI, dl, + DAG.getVTList(MVT::Other), Ops, MVT::i32, + BaseMemOperand); + }; + + // If i8 type and constant non-zero value. + if ((Src.getValueType() == MVT::i8) && !isNullConstant(Src)) + // Replicate byte to word by multiplication with 0x01010101. + SrcValueReplicated = + DAG.getNode(ISD::MUL, dl, MVT::i32, SrcValueReplicated, + DAG.getConstant(0x01010101ul, dl, MVT::i32)); + + // We limit a QC_SETWMI to 16 words or less to improve interruptibility. + // So for 1-16 words we use a single QC_SETWMI: + // + // QC_SETWMI reg1, N, 0(reg2) + // + // For 17-32 words we use two QC_SETWMI's with the first as 16 words and the + // second for the remainder: + // + // QC_SETWMI reg1, 16, 0(reg2) + // QC_SETWMI reg1, N, 64(reg2) + // + // For 33-48 words, we would like to use (16, 16, n), but that means the last + // QC_SETWMI needs an offset of 128 which the instruction doesn't support. + // So in this case we use a length of 15 for the second instruction and we do + // the rest with the third instruction. + // This means the maximum inlined number of words is 47 (for now): + // + // QC_SETWMI R2, R0, 16, 0 + // QC_SETWMI R2, R0, 15, 64 + // QC_SETWMI R2, R0, N, 124 + // + // For 48 words or more, call the target independent memset + if (NumberOfWords >= 48) + return SDValue(); + + if (NumberOfWords <= 16) { + // 1 - 16 words + return getSetwmiNode(NumberOfWords, 0); + } + + if (NumberOfWords <= 32) { + // 17 - 32 words + OutChains.push_back(getSetwmiNode(NumberOfWords - 16, 64)); + OutChains.push_back(getSetwmiNode(16, 0)); + } else { + // 33 - 47 words + OutChains.push_back(getSetwmiNode(NumberOfWords - 31, 124)); + OutChains.push_back(getSetwmiNode(15, 64)); + OutChains.push_back(getSetwmiNode(16, 0)); + } + + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains); +} diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h index 641189f8661c1..08c8d11f2b108 100644 --- a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h +++ b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h @@ -34,6 +34,12 @@ class RISCVSelectionDAGInfo : public SelectionDAGGenTargetInfo { void verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const override; + SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl, + SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, Align Alignment, + bool isVolatile, bool AlwaysInline, + MachinePointerInfo DstPtrInfo) const override; + bool hasPassthruOp(unsigned Opcode) const { return GenNodeInfo.getDesc(Opcode).TSFlags & RISCVISD::HasPassthruOpMask; } diff --git a/llvm/test/CodeGen/RISCV/xqcilsm-memset.ll b/llvm/test/CodeGen/RISCV/xqcilsm-memset.ll new file mode 100644 index 0000000000000..988bb6ffb8915 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/xqcilsm-memset.ll @@ -0,0 +1,900 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefixes=RV32I +; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+experimental-xqcilsm < %s \ +; RUN: | FileCheck %s -check-prefixes=RV32IXQCILSM + +%struct.anon = type { [16 x i32] } +%struct.anon.0 = type { [47 x i32] } +%struct.anon.1 = type { [48 x i32] } +%struct.anon.2 = type { [64 x i8] } +%struct.struct1_t = type { [16 x i32] } + +@struct1 = common dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4 +@struct4b = common dso_local local_unnamed_addr global %struct.anon.0 zeroinitializer, align 4 +@struct4b1 = common dso_local local_unnamed_addr global %struct.anon.1 zeroinitializer, align 4 +@struct2 = common dso_local local_unnamed_addr global %struct.anon.2 zeroinitializer, align 1 +@arr1 = common dso_local local_unnamed_addr global [100 x i32] zeroinitializer, align 4 +@struct1_ = common dso_local local_unnamed_addr global %struct.struct1_t zeroinitializer, align 4 + +define void @test1(ptr nocapture %p, i32 %n) nounwind { +; RV32I-LABEL: test1: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: mv a2, a1 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test1: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: mv a2, a1 +; RV32IXQCILSM-NEXT: li a1, 0 +; RV32IXQCILSM-NEXT: tail memset +entry: + tail call void @llvm.memset.p0.i32(ptr align 1 %p, i8 0, i32 %n, i1 false) + ret void +} + +declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1) + +define void @test2(ptr nocapture %p) nounwind { +; RV32I-LABEL: test2: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a1, 165 +; RV32I-NEXT: li a2, 128 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test2: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a1, 678490 +; RV32IXQCILSM-NEXT: addi a1, a1, 1445 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %p, i8 -91, i32 128, i1 false) + ret void +} + +define void @test2a(ptr nocapture %p) nounwind { +; RV32I-LABEL: test2a: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a1, 165 +; RV32I-NEXT: li a2, 188 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test2a: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a1, 678490 +; RV32IXQCILSM-NEXT: addi a1, a1, 1445 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 15, 64(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 124(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %p, i8 -91, i32 188, i1 false) + ret void +} + +define void @test2b(ptr nocapture %p) nounwind { +; RV32I-LABEL: test2b: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a1, 165 +; RV32I-NEXT: li a2, 192 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test2b: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: li a1, 165 +; RV32IXQCILSM-NEXT: li a2, 192 +; RV32IXQCILSM-NEXT: tail memset +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %p, i8 -91, i32 192, i1 false) + ret void +} + +define void @test2c(ptr nocapture %p) nounwind { +; RV32I-LABEL: test2c: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a1, 165 +; RV32I-NEXT: li a2, 128 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test2c: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a1, 678490 +; RV32IXQCILSM-NEXT: addi a1, a1, 1445 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %p, i8 -91, i32 128, i1 false) + ret void +} + +define void @test2d(ptr nocapture %p) nounwind { +; RV32I-LABEL: test2d: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a1, -91 +; RV32I-NEXT: lui a2, 1048570 +; RV32I-NEXT: lui a3, 678490 +; RV32I-NEXT: addi a2, a2, 1445 +; RV32I-NEXT: addi a3, a3, 1445 +; RV32I-NEXT: sw a3, 0(a0) +; RV32I-NEXT: sw a3, 4(a0) +; RV32I-NEXT: sh a2, 8(a0) +; RV32I-NEXT: sb a1, 10(a0) +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test2d: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: li a1, -91 +; RV32IXQCILSM-NEXT: lui a2, 1048570 +; RV32IXQCILSM-NEXT: lui a3, 678490 +; RV32IXQCILSM-NEXT: addi a2, a2, 1445 +; RV32IXQCILSM-NEXT: addi a3, a3, 1445 +; RV32IXQCILSM-NEXT: sw a3, 0(a0) +; RV32IXQCILSM-NEXT: sw a3, 4(a0) +; RV32IXQCILSM-NEXT: sh a2, 8(a0) +; RV32IXQCILSM-NEXT: sb a1, 10(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %p, i8 -91, i32 11, i1 false) + ret void +} + + +define ptr @test3(ptr %p) nounwind { +; RV32I-LABEL: test3: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a2, 256 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test3: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: li a2, 256 +; RV32IXQCILSM-NEXT: li a1, 0 +; RV32IXQCILSM-NEXT: tail memset +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %p, i8 0, i32 256, i1 false) + ret ptr %p +} + +define ptr @test3a(ptr %p) nounwind { +; RV32I-LABEL: test3a: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a2, 128 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test3a: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %p, i8 0, i32 128, i1 false) + ret ptr %p +} + +define void @test4() nounwind { +; RV32I-LABEL: test4: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(struct1) +; RV32I-NEXT: addi a0, a0, %lo(struct1) +; RV32I-NEXT: li a2, 64 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test4: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(struct1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(struct1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @struct1, i8 0, i32 64, i1 false) + ret void +} + +define void @test4a(ptr nocapture %s) nounwind { +; RV32I-LABEL: test4a: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: li a1, 166 +; RV32I-NEXT: li a2, 64 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test4a: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a1, 682602 +; RV32IXQCILSM-NEXT: addi a1, a1, 1702 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 %s, i8 -90, i32 64, i1 false) + ret void +} + +declare void @llvm.lifetime.start.p0(i64, ptr nocapture) + +declare void @llvm.lifetime.end.p0(i64, ptr nocapture) + +define void @test4b() nounwind { +; RV32I-LABEL: test4b: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: lui a0, %hi(struct4b) +; RV32I-NEXT: addi a0, a0, %lo(struct4b) +; RV32I-NEXT: li a2, 188 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: call memset +; RV32I-NEXT: lui a0, %hi(struct4b1) +; RV32I-NEXT: addi a0, a0, %lo(struct4b1) +; RV32I-NEXT: li a2, 192 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test4b: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a1, %hi(struct4b) +; RV32IXQCILSM-NEXT: addi a1, a1, %lo(struct4b) +; RV32IXQCILSM-NEXT: lui a0, %hi(struct4b1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(struct4b1) +; RV32IXQCILSM-NEXT: li a2, 192 +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 15, 64(a1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 124(a1) +; RV32IXQCILSM-NEXT: li a1, 0 +; RV32IXQCILSM-NEXT: tail memset +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @struct4b, i8 0, i32 188, i1 false) + tail call void @llvm.memset.p0.i32(ptr align 4 @struct4b1, i8 0, i32 192, i1 false) + ret void +} + +define void @test5() nounwind { +; RV32I-LABEL: test5: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(struct2) +; RV32I-NEXT: addi a0, a0, %lo(struct2) +; RV32I-NEXT: li a2, 64 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test5: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(struct2) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(struct2) +; RV32IXQCILSM-NEXT: li a2, 64 +; RV32IXQCILSM-NEXT: li a1, 0 +; RV32IXQCILSM-NEXT: tail memset +entry: + tail call void @llvm.memset.p0.i32(ptr align 1 @struct2, i8 0, i32 64, i1 false) + ret void +} + +define i32 @test6() nounwind { +; RV32I-LABEL: test6: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw zero, 12(sp) +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sw zero, 12(sp) +; RV32IXQCILSM-NEXT: li a0, 0 +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i32, align 4 + call void @llvm.memset.p0.i32(ptr align 4 %x, i8 0, i32 4, i1 false) + %0 = load i32, ptr %x, align 4 + ret i32 %0 +} + +define zeroext i8 @test6b_c() nounwind { +; RV32I-LABEL: test6b_c: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sb zero, 12(sp) +; RV32I-NEXT: lbu a0, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6b_c: +; RV32IXQCILSM: # %bb.0: +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sb zero, 12(sp) +; RV32IXQCILSM-NEXT: lbu a0, 12(sp) +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret + %x = alloca i8, align 4 + call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %x) + call void @llvm.memset.p0.i32(ptr nonnull align 4 %x, i8 0, i32 1, i1 false) + %x.0.x.0. = load volatile i8, ptr %x, align 4 + call void @llvm.lifetime.end.p0(i64 1, ptr nonnull %x) + ret i8 %x.0.x.0. +} + +define signext i16 @test6b_s() nounwind { +; RV32I-LABEL: test6b_s: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sh zero, 12(sp) +; RV32I-NEXT: lh a0, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6b_s: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sh zero, 12(sp) +; RV32IXQCILSM-NEXT: lh a0, 12(sp) +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i16, align 4 + call void @llvm.lifetime.start.p0(i64 2, ptr nonnull %x) + store i16 0, ptr %x, align 4 + %x.0.x.0. = load volatile i16, ptr %x, align 4 + call void @llvm.lifetime.end.p0(i64 2, ptr nonnull %x) + ret i16 %x.0.x.0. +} + +define i32 @test6b_l() nounwind { +; RV32I-LABEL: test6b_l: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw zero, 12(sp) +; RV32I-NEXT: lw a0, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6b_l: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sw zero, 12(sp) +; RV32IXQCILSM-NEXT: lw a0, 12(sp) +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i32, align 4 + call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %x) + store i32 0, ptr %x, align 4 + %x.0.x.0. = load volatile i32, ptr %x, align 4 + call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %x) + ret i32 %x.0.x.0. +} + +define i64 @test6b_ll() nounwind { +; RV32I-LABEL: test6b_ll: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw zero, 8(sp) +; RV32I-NEXT: sw zero, 12(sp) +; RV32I-NEXT: lw a0, 8(sp) +; RV32I-NEXT: lw a1, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6b_ll: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sw zero, 8(sp) +; RV32IXQCILSM-NEXT: sw zero, 12(sp) +; RV32IXQCILSM-NEXT: lw a0, 8(sp) +; RV32IXQCILSM-NEXT: lw a1, 12(sp) +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i64, align 8 + call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %x) + call void @llvm.memset.p0.i32(ptr nonnull align 8 %x, i8 0, i32 8, i1 false) + %x.0.x.0. = load volatile i64, ptr %x, align 8 + call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %x) + ret i64 %x.0.x.0. +} + +define zeroext i8 @test6c_c() nounwind { +; RV32I-LABEL: test6c_c: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sb zero, 15(sp) +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6c_c: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sb zero, 15(sp) +; RV32IXQCILSM-NEXT: li a0, 0 +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i8 + call void @llvm.memset.p0.i32(ptr align 1 %x, i8 0, i32 1, i1 false) + %0 = load i8, ptr %x, align 1 + ret i8 %0 +} + +define signext i16 @test6c_s() nounwind { +; RV32I-LABEL: test6c_s: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sh zero, 14(sp) +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6c_s: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sh zero, 14(sp) +; RV32IXQCILSM-NEXT: li a0, 0 +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i16 + call void @llvm.memset.p0.i32(ptr align 2 %x, i8 0, i32 2, i1 false) + %0 = load i16, ptr %x, align 2 + ret i16 %0 +} + +define i32 @test6c_l() nounwind { +; RV32I-LABEL: test6c_l: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw zero, 12(sp) +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6c_l: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sw zero, 12(sp) +; RV32IXQCILSM-NEXT: li a0, 0 +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i32, align 4 + call void @llvm.memset.p0.i32(ptr align 4 %x, i8 0, i32 4, i1 false) + %0 = load i32, ptr %x, align 4 + ret i32 %0 +} + +define i64 @test6c_ll() nounwind { +; RV32I-LABEL: test6c_ll: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw zero, 8(sp) +; RV32I-NEXT: sw zero, 12(sp) +; RV32I-NEXT: li a0, 0 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test6c_ll: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: addi sp, sp, -16 +; RV32IXQCILSM-NEXT: sw zero, 8(sp) +; RV32IXQCILSM-NEXT: sw zero, 12(sp) +; RV32IXQCILSM-NEXT: li a0, 0 +; RV32IXQCILSM-NEXT: li a1, 0 +; RV32IXQCILSM-NEXT: addi sp, sp, 16 +; RV32IXQCILSM-NEXT: ret +entry: + %x = alloca i64, align 8 + call void @llvm.memset.p0.i32(ptr align 8 %x, i8 0, i32 8, i1 false) + %0 = load i64, ptr %x, align 8 + ret i64 %0 +} + +define void @test7() nounwind { +; RV32I-LABEL: test7: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: sw zero, %lo(arr1)(a0) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: sw zero, 4(a0) +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test7: +; RV32IXQCILSM: # %bb.0: +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: sw zero, %lo(arr1)(a0) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: sw zero, 4(a0) +; RV32IXQCILSM-NEXT: ret + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 8, i1 false) + ret void +} + +define void @test7a() nounwind { +; RV32I-LABEL: test7a: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test7a: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: ret +entry: + call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 0, i1 false) + ret void +} + +define void @test7a_unalign() nounwind { +; RV32I-LABEL: test7a_unalign: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: li a1, -1 +; RV32I-NEXT: sw a1, %lo(arr1)(a0) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: sw a1, 4(a0) +; RV32I-NEXT: sw a1, 8(a0) +; RV32I-NEXT: sw a1, 12(a0) +; RV32I-NEXT: sb a1, 16(a0) +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test7a_unalign: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: li a1, -1 +; RV32IXQCILSM-NEXT: sw a1, %lo(arr1)(a0) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: sw a1, 4(a0) +; RV32IXQCILSM-NEXT: sw a1, 8(a0) +; RV32IXQCILSM-NEXT: sw a1, 12(a0) +; RV32IXQCILSM-NEXT: sb a1, 16(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 -1, i32 17, i1 false) + ret void +} + +define void @test7b() nounwind { +; RV32I-LABEL: test7b: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a1, 255 +; RV32I-NEXT: li a2, 68 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test7b: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: li a1, -1 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 1, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 -1, i32 68, i1 false) + ret void +} + +define void @test7c() nounwind { +; RV32I-LABEL: test7c: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a1, 128 +; RV32I-NEXT: li a2, 128 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test7c: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: lui a1, 526344 +; RV32IXQCILSM-NEXT: addi a1, a1, 128 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 -128, i32 128, i1 false) + ret void +} + +define void @test7d() nounwind { +; RV32I-LABEL: test7d: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a1, 13 +; RV32I-NEXT: li a2, 148 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test7d: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: lui a1, 53457 +; RV32IXQCILSM-NEXT: addi a1, a1, -755 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 15, 64(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 6, 124(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 13, i32 148, i1 false) + ret void +} + +define void @test7e() nounwind { +; RV32I-LABEL: test7e: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a1, 239 +; RV32I-NEXT: li a2, 100 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test7e: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: lui a1, 982783 +; RV32IXQCILSM-NEXT: addi a1, a1, -17 +; RV32IXQCILSM-NEXT: qc.setwmi a1, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi a1, 9, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 -17, i32 100, i1 false) + ret void +} + +define void @test8() nounwind { +; RV32I-LABEL: test8: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: sw zero, %lo(arr1)(a0) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: sw zero, 4(a0) +; RV32I-NEXT: sw zero, 8(a0) +; RV32I-NEXT: sw zero, 12(a0) +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test8: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: sw zero, %lo(arr1)(a0) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: sw zero, 4(a0) +; RV32IXQCILSM-NEXT: sw zero, 8(a0) +; RV32IXQCILSM-NEXT: sw zero, 12(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 16, i1 false) + ret void +} + +define void @test9() nounwind { +; RV32I-LABEL: test9: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: sw zero, %lo(arr1)(a0) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: sw zero, 20(a0) +; RV32I-NEXT: sw zero, 24(a0) +; RV32I-NEXT: sw zero, 28(a0) +; RV32I-NEXT: sw zero, 4(a0) +; RV32I-NEXT: sw zero, 8(a0) +; RV32I-NEXT: sw zero, 12(a0) +; RV32I-NEXT: sw zero, 16(a0) +; RV32I-NEXT: ret +; +; RV32IXQCILSM-LABEL: test9: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: sw zero, %lo(arr1)(a0) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: sw zero, 20(a0) +; RV32IXQCILSM-NEXT: sw zero, 24(a0) +; RV32IXQCILSM-NEXT: sw zero, 28(a0) +; RV32IXQCILSM-NEXT: sw zero, 4(a0) +; RV32IXQCILSM-NEXT: sw zero, 8(a0) +; RV32IXQCILSM-NEXT: sw zero, 12(a0) +; RV32IXQCILSM-NEXT: sw zero, 16(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 32, i1 false) + ret void +} + +define void @test10() nounwind { +; RV32I-LABEL: test10: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 60 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test10: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 15, 0(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 60, i1 false) + ret void +} + +define void @test11() nounwind { +; RV32I-LABEL: test11: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 64 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test11: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 64, i1 false) + ret void +} + +define void @test12() nounwind { +; RV32I-LABEL: test12: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 120 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test12: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 14, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 120, i1 false) + ret void +} + +define void @test13() nounwind { +; RV32I-LABEL: test13: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 124 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test13: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 15, 64(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 124, i1 false) + ret void +} + +define void @test14() nounwind { +; RV32I-LABEL: test14: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 180 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test14: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 15, 64(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 14, 124(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 180, i1 false) + ret void +} + +define void @test15() nounwind { +; RV32I-LABEL: test15: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 184 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test15: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 15, 64(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 15, 124(a0) +; RV32IXQCILSM-NEXT: ret +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 184, i1 false) + ret void +} + +define void @test15a() nounwind { +; RV32I-LABEL: test15a: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a1, 165 +; RV32I-NEXT: li a2, 192 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test15a: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: li a1, 165 +; RV32IXQCILSM-NEXT: li a2, 192 +; RV32IXQCILSM-NEXT: tail memset +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 -91, i32 192, i1 false) + ret void +} + +define void @test15b() nounwind { +; RV32I-LABEL: test15b: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 188 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test15b: +; RV32IXQCILSM: # %bb.0: +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 0(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 15, 64(a0) +; RV32IXQCILSM-NEXT: qc.setwmi zero, 16, 124(a0) +; RV32IXQCILSM-NEXT: ret + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 188, i1 false) + ret void +} + +define void @test15c() nounwind { +; RV32I-LABEL: test15c: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: lui a0, %hi(arr1) +; RV32I-NEXT: addi a0, a0, %lo(arr1) +; RV32I-NEXT: li a2, 192 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: tail memset +; +; RV32IXQCILSM-LABEL: test15c: +; RV32IXQCILSM: # %bb.0: # %entry +; RV32IXQCILSM-NEXT: lui a0, %hi(arr1) +; RV32IXQCILSM-NEXT: addi a0, a0, %lo(arr1) +; RV32IXQCILSM-NEXT: li a2, 192 +; RV32IXQCILSM-NEXT: li a1, 0 +; RV32IXQCILSM-NEXT: tail memset +entry: + tail call void @llvm.memset.p0.i32(ptr align 4 @arr1, i8 0, i32 192, i1 false) + ret void +}