[PATCH] D103262: [RISCV] Scale scalably-typed split argument offsets by VSCALE
Fraser Cormack via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu May 27 09:07:41 PDT 2021
frasercrmck created this revision.
frasercrmck added reviewers: HsiangKai, craig.topper, rogfer01, evandro, khchen, luismarques.
Herald added subscribers: vkmr, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, hiraditya.
frasercrmck requested review of this revision.
Herald added subscribers: llvm-commits, MaskRay.
Herald added a project: LLVM.
This patch fixes a bug in lowering scalable-vector types in RISC-V's
main calling convention. When scalable-vector types are split and passed
indirectly, the target is responsible for scaling the offset --
initially set to the known-minimum store size -- by the scalable factor.
Before this we were issuing overlapping loads or stores to the different
parts, leading to incorrect codegen.
Credit to @HsiangKai for spotting this.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D103262
Files:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/test/CodeGen/RISCV/rvv/calling-conv.ll
Index: llvm/test/CodeGen/RISCV/rvv/calling-conv.ll
===================================================================
--- llvm/test/CodeGen/RISCV/rvv/calling-conv.ll
+++ llvm/test/CodeGen/RISCV/rvv/calling-conv.ll
@@ -8,7 +8,9 @@
define <vscale x 32 x i32> @callee_scalable_vector_split_indirect(<vscale x 32 x i32> %x, <vscale x 32 x i32> %y) {
; RV32-LABEL: callee_scalable_vector_split_indirect:
; RV32: # %bb.0:
-; RV32-NEXT: addi a1, a0, 64
+; RV32-NEXT: csrr a1, vlenb
+; RV32-NEXT: slli a1, a1, 3
+; RV32-NEXT: add a1, a0, a1
; RV32-NEXT: vl8re32.v v24, (a0)
; RV32-NEXT: vl8re32.v v0, (a1)
; RV32-NEXT: vsetvli a0, zero, e32,m8,ta,mu
@@ -18,7 +20,9 @@
;
; RV64-LABEL: callee_scalable_vector_split_indirect:
; RV64: # %bb.0:
-; RV64-NEXT: addi a1, a0, 64
+; RV64-NEXT: csrr a1, vlenb
+; RV64-NEXT: slli a1, a1, 3
+; RV64-NEXT: add a1, a0, a1
; RV64-NEXT: vl8re32.v v24, (a0)
; RV64-NEXT: vl8re32.v v0, (a1)
; RV64-NEXT: vsetvli a0, zero, e32,m8,ta,mu
@@ -41,7 +45,10 @@
; RV32-NEXT: csrr a0, vlenb
; RV32-NEXT: slli a0, a0, 4
; RV32-NEXT: sub sp, sp, a0
-; RV32-NEXT: addi a0, sp, 96
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: slli a0, a0, 3
+; RV32-NEXT: addi a1, sp, 32
+; RV32-NEXT: add a0, a1, a0
; RV32-NEXT: vs8r.v v16, (a0)
; RV32-NEXT: addi a0, sp, 32
; RV32-NEXT: vs8r.v v8, (a0)
@@ -66,7 +73,10 @@
; RV64-NEXT: csrr a0, vlenb
; RV64-NEXT: slli a0, a0, 4
; RV64-NEXT: sub sp, sp, a0
-; RV64-NEXT: addi a0, sp, 88
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: slli a0, a0, 3
+; RV64-NEXT: addi a1, sp, 24
+; RV64-NEXT: add a0, a1, a0
; RV64-NEXT: vs8r.v v16, (a0)
; RV64-NEXT: addi a0, sp, 24
; RV64-NEXT: vs8r.v v8, (a0)
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7190,8 +7190,10 @@
while (i + 1 != e && Ins[i + 1].OrigArgIndex == ArgIndex) {
CCValAssign &PartVA = ArgLocs[i + 1];
unsigned PartOffset = Ins[i + 1].PartOffset - ArgPartOffset;
- SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue,
- DAG.getIntPtrConstant(PartOffset, DL));
+ SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL);
+ if (PartVA.getValVT().isScalableVector())
+ Offset = DAG.getNode(ISD::VSCALE, DL, XLenVT, Offset);
+ SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, ArgValue, Offset);
InVals.push_back(DAG.getLoad(PartVA.getValVT(), DL, Chain, Address,
MachinePointerInfo()));
++i;
@@ -7473,14 +7475,17 @@
// Calculate the total size to store. We don't have access to what we're
// actually storing other than performing the loop and collecting the
// info.
- SmallVector<std::pair<SDValue, unsigned>> Parts;
+ SmallVector<std::pair<SDValue, SDValue>> Parts;
while (i + 1 != e && Outs[i + 1].OrigArgIndex == ArgIndex) {
SDValue PartValue = OutVals[i + 1];
unsigned PartOffset = Outs[i + 1].PartOffset - ArgPartOffset;
+ SDValue Offset = DAG.getIntPtrConstant(PartOffset, DL);
EVT PartVT = PartValue.getValueType();
+ if (PartVT.isScalableVector())
+ Offset = DAG.getNode(ISD::VSCALE, DL, XLenVT, Offset);
StoredSize += PartVT.getStoreSize();
StackAlign = std::max(StackAlign, getPrefTypeAlign(PartVT, DAG));
- Parts.push_back(std::make_pair(PartValue, PartOffset));
+ Parts.push_back(std::make_pair(PartValue, Offset));
++i;
}
SDValue SpillSlot = DAG.CreateStackTemporary(StoredSize, StackAlign);
@@ -7490,9 +7495,9 @@
MachinePointerInfo::getFixedStack(MF, FI)));
for (const auto &Part : Parts) {
SDValue PartValue = Part.first;
- unsigned PartOffset = Part.second;
- SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot,
- DAG.getIntPtrConstant(PartOffset, DL));
+ SDValue PartOffset = Part.second;
+ SDValue Address =
+ DAG.getNode(ISD::ADD, DL, PtrVT, SpillSlot, PartOffset);
MemOpChains.push_back(
DAG.getStore(Chain, DL, PartValue, Address,
MachinePointerInfo::getFixedStack(MF, FI)));
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103262.348298.patch
Type: text/x-patch
Size: 4488 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210527/16b186db/attachment.bin>
More information about the llvm-commits
mailing list