[llvm] [RISCV] Implement EmitTargetCodeForMemset for Xqcilsm (PR #151555)
Sudharsan Veeravalli via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 31 09:38:13 PDT 2025
https://github.com/svs-quic created https://github.com/llvm/llvm-project/pull/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.
>From 54bd095e51ede4c9c0437fef2d4275db22ae8fb4 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Thu, 31 Jul 2025 21:42:32 +0530
Subject: [PATCH] [RISCV] Implement EmitTargetCodeForMemset for Xqcilsm
---
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 9 +
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 8 +
.../Target/RISCV/RISCVSelectionDAGInfo.cpp | 101 ++
llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.h | 6 +
llvm/test/CodeGen/RISCV/xqcilsm-memset.ll | 929 ++++++++++++++++++
5 files changed, 1053 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/xqcilsm-memset.ll
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index f223fdbef4359..b778c33083685 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1845,6 +1845,15 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
CurDAG->RemoveDeadNode(Node);
return;
}
+ case RISCVISD::QC_SETWMI: {
+ SDValue Chain = Node->getOperand(0);
+ SDVTList VTs = Node->getVTList();
+ SDValue Ops[] = {Node->getOperand(1), Node->getOperand(2),
+ Node->getOperand(3), Node->getOperand(4), Chain};
+ MachineSDNode *New = CurDAG->getMachineNode(RISCV::QC_SETWMI, DL, VTs, Ops);
+ ReplaceNode(Node, New);
+ return;
+ }
case ISD::INTRINSIC_WO_CHAIN: {
unsigned IntNo = Node->getConstantOperandVal(0);
switch (IntNo) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 52656134b7774..2479ced164927 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_StoreMultiple : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
+ SDTCisSameAs<1, 3>,
+ SDTCisPtrTy<2>,
+ SDTCisVT<3, XLenVT>]>;
+
+def qc_setwmi : RVSDNode<"QC_SETWMI", SDT_StoreMultiple,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+
def uimm5nonzero : RISCVOp<XLenVT>,
ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
diff --git a/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp b/llvm/lib/Target/RISCV/RISCVSelectionDAGInfo.cpp
index 6ecddad72c078..edfa2992711a0 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,102 @@ 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 RISCVSubtarget &Subtarget =
+ DAG.getMachineFunction().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 multiple of 4 bytes.
+ if (!((Alignment.value() & 3) == 0 && (NumberOfBytesToWrite & 3) == 0))
+ return SDValue();
+
+ SmallVector<SDValue, 8> OutChains;
+ SDValue SizeWords, OffsetSetwmi;
+ SDValue SrcValueReplicated = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, Src);
+ int NumberOfWords = NumberOfBytesToWrite / 4;
+
+ // Helper for constructing the QC_SETWMI instruction
+ auto getSetwmiNode = [&](SDValue SizeWords, SDValue OffsetSetwmi) -> SDValue {
+ SDValue Ops[] = {Chain, SrcValueReplicated, Dst, SizeWords, OffsetSetwmi};
+ return DAG.getNode(RISCVISD::QC_SETWMI, dl, MVT::Other, Ops);
+ };
+
+ bool IsZeroVal =
+ isa<ConstantSDNode>(Src) && cast<ConstantSDNode>(Src)->isZero();
+
+ // If i8 type and constant non-zero value.
+ if ((Src.getValueType() == MVT::i8) && !IsZeroVal)
+ // Replicate byte to word by multiplication with 0x01010101.
+ SrcValueReplicated = DAG.getNode(ISD::MUL, dl, MVT::i32, SrcValueReplicated,
+ DAG.getConstant(16843009, 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, 32-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 doesnt 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 <= 16) {
+ // 1 - 16 words
+ SizeWords = DAG.getTargetConstant(NumberOfWords, dl, MVT::i32);
+ SDValue OffsetSetwmi = DAG.getTargetConstant(0, dl, MVT::i32);
+ return getSetwmiNode(SizeWords, OffsetSetwmi);
+ } else if (NumberOfWords <= 47) {
+ if (NumberOfWords <= 32) {
+ // 17 - 32 words
+ SizeWords = DAG.getTargetConstant(NumberOfWords - 16, dl, MVT::i32);
+ OffsetSetwmi = DAG.getTargetConstant(64, dl, MVT::i32);
+ OutChains.push_back(getSetwmiNode(SizeWords, OffsetSetwmi));
+
+ SizeWords = DAG.getTargetConstant(16, dl, MVT::i32);
+ OffsetSetwmi = DAG.getTargetConstant(0, dl, MVT::i32);
+ OutChains.push_back(getSetwmiNode(SizeWords, OffsetSetwmi));
+ } else {
+ // 33 - 47 words
+ SizeWords = DAG.getTargetConstant(NumberOfWords - 31, dl, MVT::i32);
+ OffsetSetwmi = DAG.getTargetConstant(124, dl, MVT::i32);
+ OutChains.push_back(getSetwmiNode(SizeWords, OffsetSetwmi));
+
+ SizeWords = DAG.getTargetConstant(15, dl, MVT::i32);
+ OffsetSetwmi = DAG.getTargetConstant(64, dl, MVT::i32);
+ OutChains.push_back(getSetwmiNode(SizeWords, OffsetSetwmi));
+
+ SizeWords = DAG.getTargetConstant(16, dl, MVT::i32);
+ OffsetSetwmi = DAG.getTargetConstant(0, dl, MVT::i32);
+ OutChains.push_back(getSetwmiNode(SizeWords, OffsetSetwmi));
+ }
+ return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
+ }
+
+ // >= 48 words. Call target independent memset.
+ return SDValue();
+}
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..b0107cc1a4e03
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/xqcilsm-memset.ll
@@ -0,0 +1,929 @@
+; 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=RV32IXQCISLS
+
+%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
+;
+; RV32IXQCISLS-LABEL: test1:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: mv a2, a1
+; RV32IXQCISLS-NEXT: li a1, 0
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test2:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a1, 678490
+; RV32IXQCISLS-NEXT: addi a1, a1, 1445
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test2a:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a1, 678490
+; RV32IXQCISLS-NEXT: addi a1, a1, 1445
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 15, 64(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 124(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test2b:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: li a1, 165
+; RV32IXQCISLS-NEXT: li a2, 192
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test2c:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a1, 678490
+; RV32IXQCISLS-NEXT: addi a1, a1, 1445
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test2d:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: li a1, -91
+; RV32IXQCISLS-NEXT: lui a2, 1048570
+; RV32IXQCISLS-NEXT: lui a3, 678490
+; RV32IXQCISLS-NEXT: addi a2, a2, 1445
+; RV32IXQCISLS-NEXT: addi a3, a3, 1445
+; RV32IXQCISLS-NEXT: sw a3, 0(a0)
+; RV32IXQCISLS-NEXT: sw a3, 4(a0)
+; RV32IXQCISLS-NEXT: sh a2, 8(a0)
+; RV32IXQCISLS-NEXT: sb a1, 10(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test3:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: li a2, 256
+; RV32IXQCISLS-NEXT: li a1, 0
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test3a:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test4:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(struct1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(struct1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test4a:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a1, 682602
+; RV32IXQCISLS-NEXT: addi a1, a1, 1702
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test4b:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a1, %hi(struct4b)
+; RV32IXQCISLS-NEXT: addi a1, a1, %lo(struct4b)
+; RV32IXQCISLS-NEXT: lui a0, %hi(struct4b1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(struct4b1)
+; RV32IXQCISLS-NEXT: li a2, 192
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 15, 64(a1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 124(a1)
+; RV32IXQCISLS-NEXT: li a1, 0
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test5:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(struct2)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(struct2)
+; RV32IXQCISLS-NEXT: li a2, 64
+; RV32IXQCISLS-NEXT: li a1, 0
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test6:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sw zero, 12(sp)
+; RV32IXQCISLS-NEXT: li a0, 0
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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 i32 @test6a() nounwind {
+; RV32I-LABEL: test6a:
+; 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
+;
+; RV32IXQCISLS-LABEL: test6a:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sw zero, 12(sp)
+; RV32IXQCISLS-NEXT: lw a0, 12(sp)
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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 zeroext i8 @test6b_c() nounwind {
+; RV32I-LABEL: test6b_c:
+; RV32I: # %bb.0: # %entry
+; 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
+;
+; RV32IXQCISLS-LABEL: test6b_c:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sb zero, 12(sp)
+; RV32IXQCISLS-NEXT: lbu a0, 12(sp)
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-NEXT: ret
+entry:
+ %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
+;
+; RV32IXQCISLS-LABEL: test6b_s:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sh zero, 12(sp)
+; RV32IXQCISLS-NEXT: lh a0, 12(sp)
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test6b_l:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sw zero, 12(sp)
+; RV32IXQCISLS-NEXT: lw a0, 12(sp)
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test6b_ll:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sw zero, 8(sp)
+; RV32IXQCISLS-NEXT: sw zero, 12(sp)
+; RV32IXQCISLS-NEXT: lw a0, 8(sp)
+; RV32IXQCISLS-NEXT: lw a1, 12(sp)
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test6c_c:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sb zero, 15(sp)
+; RV32IXQCISLS-NEXT: li a0, 0
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test6c_s:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sh zero, 14(sp)
+; RV32IXQCISLS-NEXT: li a0, 0
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test6c_l:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sw zero, 12(sp)
+; RV32IXQCISLS-NEXT: li a0, 0
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test6c_ll:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: addi sp, sp, -16
+; RV32IXQCISLS-NEXT: sw zero, 8(sp)
+; RV32IXQCISLS-NEXT: sw zero, 12(sp)
+; RV32IXQCISLS-NEXT: li a0, 0
+; RV32IXQCISLS-NEXT: li a1, 0
+; RV32IXQCISLS-NEXT: addi sp, sp, 16
+; RV32IXQCISLS-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: # %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: ret
+;
+; RV32IXQCISLS-LABEL: test7:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: sw zero, %lo(arr1)(a0)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: sw zero, 4(a0)
+; RV32IXQCISLS-NEXT: ret
+entry:
+ 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
+;
+; RV32IXQCISLS-LABEL: test7a:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test7a_unalign:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: li a1, -1
+; RV32IXQCISLS-NEXT: sw a1, %lo(arr1)(a0)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: sw a1, 4(a0)
+; RV32IXQCISLS-NEXT: sw a1, 8(a0)
+; RV32IXQCISLS-NEXT: sw a1, 12(a0)
+; RV32IXQCISLS-NEXT: sb a1, 16(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test7b:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: li a1, -1
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 1, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test7c:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: lui a1, 526344
+; RV32IXQCISLS-NEXT: addi a1, a1, 128
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test7d:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: lui a1, 53457
+; RV32IXQCISLS-NEXT: addi a1, a1, -755
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 15, 64(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 6, 124(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test7e:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: lui a1, 982783
+; RV32IXQCISLS-NEXT: addi a1, a1, -17
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi a1, 9, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test8:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: sw zero, %lo(arr1)(a0)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: sw zero, 4(a0)
+; RV32IXQCISLS-NEXT: sw zero, 8(a0)
+; RV32IXQCISLS-NEXT: sw zero, 12(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test9:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: sw zero, %lo(arr1)(a0)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: sw zero, 20(a0)
+; RV32IXQCISLS-NEXT: sw zero, 24(a0)
+; RV32IXQCISLS-NEXT: sw zero, 28(a0)
+; RV32IXQCISLS-NEXT: sw zero, 4(a0)
+; RV32IXQCISLS-NEXT: sw zero, 8(a0)
+; RV32IXQCISLS-NEXT: sw zero, 12(a0)
+; RV32IXQCISLS-NEXT: sw zero, 16(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test10:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 15, 0(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test11:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test12:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 14, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test13:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 15, 64(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test14:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 15, 64(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 14, 124(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test15:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 15, 64(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 15, 124(a0)
+; RV32IXQCISLS-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
+;
+; RV32IXQCISLS-LABEL: test15a:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: li a1, 165
+; RV32IXQCISLS-NEXT: li a2, 192
+; RV32IXQCISLS-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: # %entry
+; 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
+;
+; RV32IXQCISLS-LABEL: test15b:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 0(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 15, 64(a0)
+; RV32IXQCISLS-NEXT: qc.setwmi zero, 16, 124(a0)
+; RV32IXQCISLS-NEXT: ret
+entry:
+ 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
+;
+; RV32IXQCISLS-LABEL: test15c:
+; RV32IXQCISLS: # %bb.0: # %entry
+; RV32IXQCISLS-NEXT: lui a0, %hi(arr1)
+; RV32IXQCISLS-NEXT: addi a0, a0, %lo(arr1)
+; RV32IXQCISLS-NEXT: li a2, 192
+; RV32IXQCISLS-NEXT: li a1, 0
+; RV32IXQCISLS-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