[RegisterScavenger][RISCV] Don't search for FrameSetup instrs if we were searching...
authorluxufan <luxufan@iscas.ac.cn>
Fri, 18 Nov 2022 06:56:36 +0000 (14:56 +0800)
committerluxufan <luxufan@iscas.ac.cn>
Fri, 18 Nov 2022 07:13:52 +0000 (15:13 +0800)
Otherwise, the spill position may point to position where before
FrameSetup instructions. In which case, the spill instruction may store
to caller's frame since the stack pointer has not been adjustted.

Fixes https://github.com/llvm/llvm-project/issues/58286

Reviewed By: craig.topper

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

llvm/lib/CodeGen/RegisterScavenging.cpp
llvm/test/CodeGen/RISCV/out-of-reach-emergency-slot.mir
llvm/test/CodeGen/RISCV/pr58286.ll [new file with mode: 0644]
llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir

index 289d31b..9a461b8 100644 (file)
@@ -394,6 +394,13 @@ findSurvivorBackwards(const MachineRegisterInfo &MRI,
         Used.accumulate(*std::next(From));
     }
     if (FoundTo) {
+      // Don't search to FrameSetup instructions if we were searching from
+      // Non-FrameSetup instructions. Otherwise, the spill position may point
+      // before FrameSetup instructions.
+      if (!From->getFlag(MachineInstr::FrameSetup) &&
+          MI.getFlag(MachineInstr::FrameSetup))
+        break;
+
       if (Survivor == 0 || !Used.available(Survivor)) {
         MCPhysReg AvilableReg = 0;
         for (MCPhysReg Reg : AllocationOrder) {
index cee38fe..28f36c2 100644 (file)
 # DEBUG: Adjusting emergency spill slots!
 # DEBUG: Adjusting offset of emergency spill slot #4 from -4112 to -8192
 
+# FIXME: The code generated here is incorrect. It stores a0 to 0(sp) before
+# sub sp, sp, a0 but restores it after sub sp, sp, a0. We may need to implement
+# the target hook saveScavengerRegister to solve it.
+
 --- |
   ; ModuleID = 'reduced.ll'
   source_filename = "frame_layout-1253b1.cpp"
   ; CHECK-NEXT:    sd ra, 2024(sp) # 8-byte Folded Spill
   ; CHECK-NEXT:    sd s0, 2016(sp) # 8-byte Folded Spill
   ; CHECK-NEXT:    addi s0, sp, 2032
+  ; CHECK-NEXT:    sd a0, 0(sp)
+  ; CHECK-NEXT:    lui a0, 2
+  ; CHECK-NEXT:    addiw a0, a0, -2032
+  ; CHECK-NEXT:    sub sp, sp, a0
+  ; CHECK-NEXT:    srli a0, sp, 12
+  ; CHECK-NEXT:    slli sp, a0, 12
+  ; CHECK-NEXT:    ld a0, 0(sp)
   ; CHECK-NEXT:    sd a1, 0(sp)
-  ; CHECK-NEXT:    lui a1, 2
-  ; CHECK-NEXT:    addiw a1, a1, -2032
-  ; CHECK-NEXT:    sub sp, sp, a1
-  ; CHECK-NEXT:    srli a1, sp, 12
-  ; CHECK-NEXT:    slli sp, a1, 12
   ; CHECK-NEXT:    lui a1, 1
   ; CHECK-NEXT:    addiw a1, a1, -8
   ; CHECK-NEXT:    add a1, sp, a1
@@ -76,3 +82,5 @@ body:             |
     PseudoRET
 
 ...
+## NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+# DEBUG: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/pr58286.ll b/llvm/test/CodeGen/RISCV/pr58286.ll
new file mode 100644 (file)
index 0000000..a3b47ee
--- /dev/null
@@ -0,0 +1,281 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv64 < %s | FileCheck --check-prefix=RV64I %s
+; RUN: llc -mtriple=riscv32 < %s | FileCheck --check-prefix=RV32I %s
+@var = external global i32
+
+define void @func() {
+; RV64I-LABEL: func:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    lui a0, 1
+; RV64I-NEXT:    addiw a0, a0, 16
+; RV64I-NEXT:    sub sp, sp, a0
+; RV64I-NEXT:    .cfi_def_cfa_offset 4112
+; RV64I-NEXT:    lui a0, %hi(var)
+; RV64I-NEXT:    lw a1, %lo(var)(a0)
+; RV64I-NEXT:    lw a2, %lo(var)(a0)
+; RV64I-NEXT:    lw a3, %lo(var)(a0)
+; RV64I-NEXT:    lw a4, %lo(var)(a0)
+; RV64I-NEXT:    lw a5, %lo(var)(a0)
+; RV64I-NEXT:    lw a6, %lo(var)(a0)
+; RV64I-NEXT:    lw a7, %lo(var)(a0)
+; RV64I-NEXT:    lw t0, %lo(var)(a0)
+; RV64I-NEXT:    lw t1, %lo(var)(a0)
+; RV64I-NEXT:    lw t2, %lo(var)(a0)
+; RV64I-NEXT:    lw t3, %lo(var)(a0)
+; RV64I-NEXT:    lw t4, %lo(var)(a0)
+; RV64I-NEXT:    lw t5, %lo(var)(a0)
+; RV64I-NEXT:    lw t6, %lo(var)(a0)
+; RV64I-NEXT:    sd s0, 0(sp)
+; RV64I-NEXT:    lui s0, 1
+; RV64I-NEXT:    addiw s0, s0, 12
+; RV64I-NEXT:    add s0, sp, s0
+; RV64I-NEXT:    sw a1, 0(s0)
+; RV64I-NEXT:    ld s0, 0(sp)
+; RV64I-NEXT:    sw a1, %lo(var)(a0)
+; RV64I-NEXT:    sw a2, %lo(var)(a0)
+; RV64I-NEXT:    sw a3, %lo(var)(a0)
+; RV64I-NEXT:    sw a4, %lo(var)(a0)
+; RV64I-NEXT:    sw a5, %lo(var)(a0)
+; RV64I-NEXT:    sw a6, %lo(var)(a0)
+; RV64I-NEXT:    sw a7, %lo(var)(a0)
+; RV64I-NEXT:    sw t0, %lo(var)(a0)
+; RV64I-NEXT:    sw t1, %lo(var)(a0)
+; RV64I-NEXT:    sw t2, %lo(var)(a0)
+; RV64I-NEXT:    sw t3, %lo(var)(a0)
+; RV64I-NEXT:    sw t4, %lo(var)(a0)
+; RV64I-NEXT:    sw t5, %lo(var)(a0)
+; RV64I-NEXT:    sw t6, %lo(var)(a0)
+; RV64I-NEXT:    lui a0, 1
+; RV64I-NEXT:    addiw a0, a0, 16
+; RV64I-NEXT:    add sp, sp, a0
+; RV64I-NEXT:    ret
+;
+; RV32I-LABEL: func:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a0, 1
+; RV32I-NEXT:    addi a0, a0, 16
+; RV32I-NEXT:    sub sp, sp, a0
+; RV32I-NEXT:    .cfi_def_cfa_offset 4112
+; RV32I-NEXT:    lui a0, %hi(var)
+; RV32I-NEXT:    lw a1, %lo(var)(a0)
+; RV32I-NEXT:    lw a2, %lo(var)(a0)
+; RV32I-NEXT:    lw a3, %lo(var)(a0)
+; RV32I-NEXT:    lw a4, %lo(var)(a0)
+; RV32I-NEXT:    lw a5, %lo(var)(a0)
+; RV32I-NEXT:    lw a6, %lo(var)(a0)
+; RV32I-NEXT:    lw a7, %lo(var)(a0)
+; RV32I-NEXT:    lw t0, %lo(var)(a0)
+; RV32I-NEXT:    lw t1, %lo(var)(a0)
+; RV32I-NEXT:    lw t2, %lo(var)(a0)
+; RV32I-NEXT:    lw t3, %lo(var)(a0)
+; RV32I-NEXT:    lw t4, %lo(var)(a0)
+; RV32I-NEXT:    lw t5, %lo(var)(a0)
+; RV32I-NEXT:    lw t6, %lo(var)(a0)
+; RV32I-NEXT:    sw s0, 0(sp)
+; RV32I-NEXT:    lui s0, 1
+; RV32I-NEXT:    addi s0, s0, 12
+; RV32I-NEXT:    add s0, sp, s0
+; RV32I-NEXT:    sw a1, 0(s0)
+; RV32I-NEXT:    lw s0, 0(sp)
+; RV32I-NEXT:    sw a1, %lo(var)(a0)
+; RV32I-NEXT:    sw a2, %lo(var)(a0)
+; RV32I-NEXT:    sw a3, %lo(var)(a0)
+; RV32I-NEXT:    sw a4, %lo(var)(a0)
+; RV32I-NEXT:    sw a5, %lo(var)(a0)
+; RV32I-NEXT:    sw a6, %lo(var)(a0)
+; RV32I-NEXT:    sw a7, %lo(var)(a0)
+; RV32I-NEXT:    sw t0, %lo(var)(a0)
+; RV32I-NEXT:    sw t1, %lo(var)(a0)
+; RV32I-NEXT:    sw t2, %lo(var)(a0)
+; RV32I-NEXT:    sw t3, %lo(var)(a0)
+; RV32I-NEXT:    sw t4, %lo(var)(a0)
+; RV32I-NEXT:    sw t5, %lo(var)(a0)
+; RV32I-NEXT:    sw t6, %lo(var)(a0)
+; RV32I-NEXT:    lui a0, 1
+; RV32I-NEXT:    addi a0, a0, 16
+; RV32I-NEXT:    add sp, sp, a0
+; RV32I-NEXT:    ret
+  %space = alloca i32, align 4
+  %stackspace = alloca[1024 x i32], align 4
+
+  ;; Load values to increase register pressure.
+  %v0 = load volatile i32, i32* @var
+  %v1 = load volatile i32, i32* @var
+  %v2 = load volatile i32, i32* @var
+  %v3 = load volatile i32, i32* @var
+  %v4 = load volatile i32, i32* @var
+  %v5 = load volatile i32, i32* @var
+  %v6 = load volatile i32, i32* @var
+  %v7 = load volatile i32, i32* @var
+  %v8 = load volatile i32, i32* @var
+  %v9 = load volatile i32, i32* @var
+  %v10 = load volatile i32, i32* @var
+  %v11 = load volatile i32, i32* @var
+  %v12 = load volatile i32, i32* @var
+  %v13 = load volatile i32, i32* @var
+
+  store volatile i32 %v0, i32* %space
+
+  ;; store values so they are used.
+  store volatile i32 %v0, i32* @var
+  store volatile i32 %v1, i32* @var
+  store volatile i32 %v2, i32* @var
+  store volatile i32 %v3, i32* @var
+  store volatile i32 %v4, i32* @var
+  store volatile i32 %v5, i32* @var
+  store volatile i32 %v6, i32* @var
+  store volatile i32 %v7, i32* @var
+  store volatile i32 %v8, i32* @var
+  store volatile i32 %v9, i32* @var
+  store volatile i32 %v10, i32* @var
+  store volatile i32 %v11, i32* @var
+  store volatile i32 %v12, i32* @var
+  store volatile i32 %v13, i32* @var
+
+  ret void
+}
+
+define void @shrink_wrap(i1 %c) {
+; RV64I-LABEL: shrink_wrap:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    andi a0, a0, 1
+; RV64I-NEXT:    bnez a0, .LBB1_2
+; RV64I-NEXT:  # %bb.1: # %bar
+; RV64I-NEXT:    lui a0, 1
+; RV64I-NEXT:    addiw a0, a0, 16
+; RV64I-NEXT:    sub sp, sp, a0
+; RV64I-NEXT:    .cfi_def_cfa_offset 4112
+; RV64I-NEXT:    lui a0, %hi(var)
+; RV64I-NEXT:    lw a1, %lo(var)(a0)
+; RV64I-NEXT:    lw a2, %lo(var)(a0)
+; RV64I-NEXT:    lw a3, %lo(var)(a0)
+; RV64I-NEXT:    lw a4, %lo(var)(a0)
+; RV64I-NEXT:    lw a5, %lo(var)(a0)
+; RV64I-NEXT:    lw a6, %lo(var)(a0)
+; RV64I-NEXT:    lw a7, %lo(var)(a0)
+; RV64I-NEXT:    lw t0, %lo(var)(a0)
+; RV64I-NEXT:    lw t1, %lo(var)(a0)
+; RV64I-NEXT:    lw t2, %lo(var)(a0)
+; RV64I-NEXT:    lw t3, %lo(var)(a0)
+; RV64I-NEXT:    lw t4, %lo(var)(a0)
+; RV64I-NEXT:    lw t5, %lo(var)(a0)
+; RV64I-NEXT:    lw t6, %lo(var)(a0)
+; RV64I-NEXT:    sd s0, 0(sp)
+; RV64I-NEXT:    lui s0, 1
+; RV64I-NEXT:    addiw s0, s0, 12
+; RV64I-NEXT:    add s0, sp, s0
+; RV64I-NEXT:    sw a1, 0(s0)
+; RV64I-NEXT:    ld s0, 0(sp)
+; RV64I-NEXT:    sw a1, %lo(var)(a0)
+; RV64I-NEXT:    sw a2, %lo(var)(a0)
+; RV64I-NEXT:    sw a3, %lo(var)(a0)
+; RV64I-NEXT:    sw a4, %lo(var)(a0)
+; RV64I-NEXT:    sw a5, %lo(var)(a0)
+; RV64I-NEXT:    sw a6, %lo(var)(a0)
+; RV64I-NEXT:    sw a7, %lo(var)(a0)
+; RV64I-NEXT:    sw t0, %lo(var)(a0)
+; RV64I-NEXT:    sw t1, %lo(var)(a0)
+; RV64I-NEXT:    sw t2, %lo(var)(a0)
+; RV64I-NEXT:    sw t3, %lo(var)(a0)
+; RV64I-NEXT:    sw t4, %lo(var)(a0)
+; RV64I-NEXT:    sw t5, %lo(var)(a0)
+; RV64I-NEXT:    sw t6, %lo(var)(a0)
+; RV64I-NEXT:    lui a0, 1
+; RV64I-NEXT:    addiw a0, a0, 16
+; RV64I-NEXT:    add sp, sp, a0
+; RV64I-NEXT:  .LBB1_2: # %foo
+; RV64I-NEXT:    ret
+;
+; RV32I-LABEL: shrink_wrap:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    andi a0, a0, 1
+; RV32I-NEXT:    bnez a0, .LBB1_2
+; RV32I-NEXT:  # %bb.1: # %bar
+; RV32I-NEXT:    lui a0, 1
+; RV32I-NEXT:    addi a0, a0, 16
+; RV32I-NEXT:    sub sp, sp, a0
+; RV32I-NEXT:    .cfi_def_cfa_offset 4112
+; RV32I-NEXT:    lui a0, %hi(var)
+; RV32I-NEXT:    lw a1, %lo(var)(a0)
+; RV32I-NEXT:    lw a2, %lo(var)(a0)
+; RV32I-NEXT:    lw a3, %lo(var)(a0)
+; RV32I-NEXT:    lw a4, %lo(var)(a0)
+; RV32I-NEXT:    lw a5, %lo(var)(a0)
+; RV32I-NEXT:    lw a6, %lo(var)(a0)
+; RV32I-NEXT:    lw a7, %lo(var)(a0)
+; RV32I-NEXT:    lw t0, %lo(var)(a0)
+; RV32I-NEXT:    lw t1, %lo(var)(a0)
+; RV32I-NEXT:    lw t2, %lo(var)(a0)
+; RV32I-NEXT:    lw t3, %lo(var)(a0)
+; RV32I-NEXT:    lw t4, %lo(var)(a0)
+; RV32I-NEXT:    lw t5, %lo(var)(a0)
+; RV32I-NEXT:    lw t6, %lo(var)(a0)
+; RV32I-NEXT:    sw s0, 0(sp)
+; RV32I-NEXT:    lui s0, 1
+; RV32I-NEXT:    addi s0, s0, 12
+; RV32I-NEXT:    add s0, sp, s0
+; RV32I-NEXT:    sw a1, 0(s0)
+; RV32I-NEXT:    lw s0, 0(sp)
+; RV32I-NEXT:    sw a1, %lo(var)(a0)
+; RV32I-NEXT:    sw a2, %lo(var)(a0)
+; RV32I-NEXT:    sw a3, %lo(var)(a0)
+; RV32I-NEXT:    sw a4, %lo(var)(a0)
+; RV32I-NEXT:    sw a5, %lo(var)(a0)
+; RV32I-NEXT:    sw a6, %lo(var)(a0)
+; RV32I-NEXT:    sw a7, %lo(var)(a0)
+; RV32I-NEXT:    sw t0, %lo(var)(a0)
+; RV32I-NEXT:    sw t1, %lo(var)(a0)
+; RV32I-NEXT:    sw t2, %lo(var)(a0)
+; RV32I-NEXT:    sw t3, %lo(var)(a0)
+; RV32I-NEXT:    sw t4, %lo(var)(a0)
+; RV32I-NEXT:    sw t5, %lo(var)(a0)
+; RV32I-NEXT:    sw t6, %lo(var)(a0)
+; RV32I-NEXT:    lui a0, 1
+; RV32I-NEXT:    addi a0, a0, 16
+; RV32I-NEXT:    add sp, sp, a0
+; RV32I-NEXT:  .LBB1_2: # %foo
+; RV32I-NEXT:    ret
+  %space = alloca i32, align 4
+  %stackspace = alloca[1024 x i32], align 4
+  br i1 %c, label %foo, label %bar
+
+bar:
+
+  ;; Load values to increase register pressure.
+  %v0 = load volatile i32, i32* @var
+  %v1 = load volatile i32, i32* @var
+  %v2 = load volatile i32, i32* @var
+  %v3 = load volatile i32, i32* @var
+  %v4 = load volatile i32, i32* @var
+  %v5 = load volatile i32, i32* @var
+  %v6 = load volatile i32, i32* @var
+  %v7 = load volatile i32, i32* @var
+  %v8 = load volatile i32, i32* @var
+  %v9 = load volatile i32, i32* @var
+  %v10 = load volatile i32, i32* @var
+  %v11 = load volatile i32, i32* @var
+  %v12 = load volatile i32, i32* @var
+  %v13 = load volatile i32, i32* @var
+
+  store volatile i32 %v0, i32* %space
+
+  ;; store values so they are used.
+  store volatile i32 %v0, i32* @var
+  store volatile i32 %v1, i32* @var
+  store volatile i32 %v2, i32* @var
+  store volatile i32 %v3, i32* @var
+  store volatile i32 %v4, i32* @var
+  store volatile i32 %v5, i32* @var
+  store volatile i32 %v6, i32* @var
+  store volatile i32 %v7, i32* @var
+  store volatile i32 %v8, i32* @var
+  store volatile i32 %v9, i32* @var
+  store volatile i32 %v10, i32* @var
+  store volatile i32 %v11, i32* @var
+  store volatile i32 %v12, i32* @var
+  store volatile i32 %v13, i32* @var
+  br label %foo
+
+foo:
+  ret void
+}
index 579957a..8359b3c 100644 (file)
@@ -25,7 +25,9 @@
   ; CHECK-NEXT:    mul a0, a0, a1
   ; CHECK-NEXT:    ld a1, 0(sp)
   ; CHECK-NEXT:    sub sp, sp, a0
+  ; CHECK-NEXT:    ld a0, 8(sp)
   ; CHECK-NEXT:    andi sp, sp, -128
+  ; CHECK-NEXT:    sd a0, 8(sp)
   ; CHECK-NEXT:    lui a0, 1
   ; CHECK-NEXT:    addiw a0, a0, -1808
   ; CHECK-NEXT:    add a0, sp, a0