[RegisterScavenger][RISCV] Don't search for FrameSetup instrs if we were searching from Non-FrameSetup instrs

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
This commit is contained in:
luxufan
2022-11-18 14:56:36 +08:00
parent f034c98af0
commit 18c5f3c35d
4 changed files with 303 additions and 5 deletions

View 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) {

View File

@@ -10,6 +10,10 @@
# 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"
@@ -24,12 +28,14 @@
; 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: {{.*}}

View File

@@ -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
}

View 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