[llvm] c9684e5 - [RISCV] Implement EmitTargetCodeForMemset for Xqcilsm (#151555)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 4 00:21:18 PDT 2025


Author: Sudharsan Veeravalli
Date: 2025-08-04T12:51:14+05:30
New Revision: c9684e58923babef7b994846b2208a05f3e3b31b

URL: https://github.com/llvm/llvm-project/commit/c9684e58923babef7b994846b2208a05f3e3b31b
DIFF: https://github.com/llvm/llvm-project/commit/c9684e58923babef7b994846b2208a05f3e3b31b.diff

LOG: [RISCV] Implement EmitTargetCodeForMemset for Xqcilsm (#151555)

This patch adds support for converting memset calls to one or more
`QC_SETWMI` instructions when beneficial. We only handle aligned memset
calls for now.

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 number of words handled 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.

Added: 
    llvm/test/CodeGen/RISCV/xqcilsm-memset.ll

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
    llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
    llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h

Removed: 
    


################################################################################
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<XLenVT>,
                    ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
@@ -27,6 +35,8 @@ def uimm5nonzero : RISCVOp<XLenVT>,
   }];
 }
 
+def tuimm5nonzero : TImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]>;
+
 def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
   [{return (Imm > 3) && isUInt<5>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<5, "GT3">;
@@ -92,6 +102,8 @@ def uimm5slist : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
   }];
 }
 
+def tuimm7_lsb00 : TImmLeaf<XLenVT,[{return isShiftedUInt<5, 2>(Imm);}]>;
+
 def uimm10 : RISCVUImmLeafOp<10>;
 
 def uimm11 : RISCVUImmLeafOp<11>;
@@ -1566,6 +1578,11 @@ def : QCISELECTIICCPat <SETEQ,  QC_SELECTIIEQ>;
 def : QCISELECTIICCPat <SETNE,  QC_SELECTIINE>;
 } // 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<RISCVSubtarget>();
+  // 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<ConstantSDNode>(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<SDValue, 8> 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] }
+
+ at struct1 = common dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4
+ at struct4b = common dso_local local_unnamed_addr global %struct.anon.0 zeroinitializer, align 4
+ at struct4b1 = common dso_local local_unnamed_addr global %struct.anon.1 zeroinitializer, align 4
+ at struct2 = common dso_local local_unnamed_addr global %struct.anon.2 zeroinitializer, align 1
+ at arr1 = common dso_local local_unnamed_addr global [100 x i32] zeroinitializer, align 4
+ at 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
+}


        


More information about the llvm-commits mailing list