[llvm] d8ec2b1 - [RISCV] Fix the calculation of the offset of Zvlsseg spilling.

Hsiangkai Wang via llvm-commits llvm-commits at lists.llvm.org
Mon May 10 19:46:56 PDT 2021


Author: Hsiangkai Wang
Date: 2021-05-11T10:13:18+08:00
New Revision: d8ec2b183e9243366e3a0cd1116dbe879856b333

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

LOG: [RISCV] Fix the calculation of the offset of Zvlsseg spilling.

For Zvlsseg spilling, we need to convert the pseudo instructions
into multiple vector load/store instructions with appropriate offsets.
For example, for PseudoVSPILL3_M2, we need to convert it to

VS2R %v2, %base
ADDI %base, %base, (vlenb x 2)
VS2R %v4, %base
ADDI %base, %base, (vlenb x 2)
VS2R %v6, %base

We need to keep the size of the offset in the pseudo spilling instructions.
In this case, it is (vlenb x 2).

In the original implementation, we use the size of frame objects divide the
number of vectors in zvlsseg types. The size of frame objects is not
necessary exactly the same as the spilling data. It may be larger than
it. So, we change it to (VLENB x LMUL) in this patch. The calculation is
more direct and easy to understand.

Differential Revision: https://reviews.llvm.org/D101869

Added: 
    llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir

Modified: 
    llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 8edfa9ff09f7..730e9992d7c1 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -300,14 +300,19 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
       MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
   }
 
-  MachineFrameInfo &MFI = MF.getFrameInfo();
   auto ZvlssegInfo = TII->isRVVSpillForZvlsseg(MI.getOpcode());
   if (ZvlssegInfo) {
-    int64_t ScalableValue = MFI.getObjectSize(FrameIndex) / ZvlssegInfo->first;
-    Register FactorRegister =
-        TII->getVLENFactoredAmount(MF, MBB, II, ScalableValue);
-    MI.getOperand(FIOperandNum + 1)
-        .ChangeToRegister(FactorRegister, /*isDef=*/false);
+    Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+    BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL);
+    uint32_t ShiftAmount = Log2_32(ZvlssegInfo->second);
+    if (ShiftAmount != 0)
+      BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VL)
+          .addReg(VL)
+          .addImm(ShiftAmount);
+    // The last argument of pseudo spilling opcode for zvlsseg is the length of
+    // one element of zvlsseg types. For example, for vint32m2x2_t, it will be
+    // the length of vint32m2_t.
+    MI.getOperand(FIOperandNum + 1).ChangeToRegister(VL, /*isDef=*/false);
   }
 }
 

diff  --git a/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir b/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir
new file mode 100644
index 000000000000..40ea93c87244
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir
@@ -0,0 +1,49 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -march=riscv64 -stop-after=prologepilog %s -o - 2>&1 | FileCheck %s
+
+--- |
+  target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
+  target triple = "riscv64"
+
+  define void @zvlsseg_spill(i64 *%base, i64 %vl) {
+    ret void
+  }
+...
+---
+name:    zvlsseg_spill
+tracksRegLiveness: true
+stack:
+  - { id: 0, offset: 0, size: 64, alignment: 8, stack-id: scalable-vector }
+body: |
+  bb.0:
+    liveins: $x10, $x11
+
+    ; CHECK-LABEL: name: zvlsseg_spill
+    ; CHECK: liveins: $x10, $x11
+    ; CHECK: $x2 = frame-setup ADDI $x2, -16
+    ; CHECK: CFI_INSTRUCTION def_cfa_offset 16
+    ; CHECK: $x12 = PseudoReadVLENB
+    ; CHECK: $x12 = SLLI killed $x12, 3
+    ; CHECK: $x2 = SUB $x2, killed $x12
+    ; CHECK: dead renamable $x11 = PseudoVSETVLI killed renamable $x11, 88, implicit-def $vl, implicit-def $vtype
+    ; CHECK: $v0_v1_v2_v3_v4_v5_v6 = PseudoVLSEG7E64_V_M1 renamable $x10, $noreg, 6, implicit $vl, implicit $vtype
+    ; CHECK: $x11 = ADDI $x2, 16
+    ; CHECK: $x12 = PseudoReadVLENB
+    ; CHECK: PseudoVSPILL7_M1 killed renamable $v0_v1_v2_v3_v4_v5_v6, killed $x11, killed $x12
+    ; CHECK: $x11 = ADDI $x2, 16
+    ; CHECK: $x12 = PseudoReadVLENB
+    ; CHECK: dead renamable $v7_v8_v9_v10_v11_v12_v13 = PseudoVRELOAD7_M1 killed $x11, killed $x12, implicit-def $v8
+    ; CHECK: VS1R_V killed $v8, killed renamable $x10
+    ; CHECK: $x10 = PseudoReadVLENB
+    ; CHECK: $x10 = SLLI killed $x10, 3
+    ; CHECK: $x2 = ADD $x2, killed $x10
+    ; CHECK: $x2 = frame-destroy ADDI $x2, 16
+    ; CHECK: PseudoRET
+    %0:gpr = COPY $x10
+    %1:gpr = COPY $x11
+    $v0_v1_v2_v3_v4_v5_v6 = PseudoVLSEG7E64_V_M1 %0, %1, 6, implicit $vl, implicit $vtype
+    PseudoVSPILL7_M1 killed renamable $v0_v1_v2_v3_v4_v5_v6, %stack.0, $x0
+    renamable $v7_v8_v9_v10_v11_v12_v13 = PseudoVRELOAD7_M1 %stack.0, $x0
+    VS1R_V killed $v8, %0:gpr
+    PseudoRET
+...


        


More information about the llvm-commits mailing list