Skip to content

Commit 52af23f

Browse files
authored
[RISCV] Add stack probing in eliminateCallFramePseudoInstr (#139731)
Stack clash protection code was missing from RISCVFrameLowering::eliminateCallFramePseudoInstr, calling allocateStack fixes it. This patch also fixes the tests in stack-probing-dynamic.ll that should be testing the stack allocation before a function call.
1 parent ec44c74 commit 52af23f

File tree

2 files changed

+74
-27
lines changed

2 files changed

+74
-27
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,9 +1813,22 @@ MachineBasicBlock::iterator RISCVFrameLowering::eliminateCallFramePseudoInstr(
18131813
if (MI->getOpcode() == RISCV::ADJCALLSTACKDOWN)
18141814
Amount = -Amount;
18151815

1816-
const RISCVRegisterInfo &RI = *STI.getRegisterInfo();
1817-
RI.adjustReg(MBB, MI, DL, SPReg, SPReg, StackOffset::getFixed(Amount),
1818-
MachineInstr::NoFlags, getStackAlign());
1816+
const RISCVTargetLowering *TLI =
1817+
MF.getSubtarget<RISCVSubtarget>().getTargetLowering();
1818+
int64_t ProbeSize = TLI->getStackProbeSize(MF, getStackAlign());
1819+
if (TLI->hasInlineStackProbe(MF) && -Amount >= ProbeSize) {
1820+
// When stack probing is enabled, the decrement of SP may need to be
1821+
// probed. We can handle both the decrement and the probing in
1822+
// allocateStack.
1823+
bool DynAllocation =
1824+
MF.getInfo<RISCVMachineFunctionInfo>()->hasDynamicAllocation();
1825+
allocateStack(MBB, MI, MF, -Amount, -Amount, !hasFP(MF),
1826+
/*NeedProbe=*/true, ProbeSize, DynAllocation);
1827+
} else {
1828+
const RISCVRegisterInfo &RI = *STI.getRegisterInfo();
1829+
RI.adjustReg(MBB, MI, DL, SPReg, SPReg, StackOffset::getFixed(Amount),
1830+
MachineInstr::NoFlags, getStackAlign());
1831+
}
18191832
}
18201833
}
18211834

llvm/test/CodeGen/RISCV/rvv/stack-probing-dynamic.ll

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ define void @dynamic_align_8192(i64 %size, ptr %out) #0 {
361361
; If a function has variable-sized stack objects, then any function calls which
362362
; need to pass arguments on the stack must allocate the stack space for them
363363
; dynamically, to ensure they are at the bottom of the frame.
364-
define void @no_reserved_call_frame(i64 %n, i32 %dummy) #0 {
364+
define void @no_reserved_call_frame(i64 %n) #0 {
365365
; RV64I-LABEL: no_reserved_call_frame:
366366
; RV64I: # %bb.0: # %entry
367367
; RV64I-NEXT: addi sp, sp, -16
@@ -377,15 +377,20 @@ define void @no_reserved_call_frame(i64 %n, i32 %dummy) #0 {
377377
; RV64I-NEXT: addi a0, a0, 15
378378
; RV64I-NEXT: andi a0, a0, -16
379379
; RV64I-NEXT: sub a0, sp, a0
380-
; RV64I-NEXT: lui a2, 1
380+
; RV64I-NEXT: lui a1, 1
381381
; RV64I-NEXT: .LBB4_1: # %entry
382382
; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
383-
; RV64I-NEXT: sub sp, sp, a2
383+
; RV64I-NEXT: sub sp, sp, a1
384384
; RV64I-NEXT: sd zero, 0(sp)
385385
; RV64I-NEXT: blt a0, sp, .LBB4_1
386386
; RV64I-NEXT: # %bb.2: # %entry
387387
; RV64I-NEXT: mv sp, a0
388+
; RV64I-NEXT: lui a1, 1
389+
; RV64I-NEXT: sub sp, sp, a1
390+
; RV64I-NEXT: sd zero, 0(sp)
388391
; RV64I-NEXT: call callee_stack_args
392+
; RV64I-NEXT: lui a0, 1
393+
; RV64I-NEXT: add sp, sp, a0
389394
; RV64I-NEXT: addi sp, s0, -16
390395
; RV64I-NEXT: .cfi_def_cfa sp, 16
391396
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
@@ -407,20 +412,27 @@ define void @no_reserved_call_frame(i64 %n, i32 %dummy) #0 {
407412
; RV32I-NEXT: .cfi_offset s0, -8
408413
; RV32I-NEXT: addi s0, sp, 16
409414
; RV32I-NEXT: .cfi_def_cfa s0, 0
410-
; RV32I-NEXT: mv a1, a2
411415
; RV32I-NEXT: slli a0, a0, 2
412416
; RV32I-NEXT: addi a0, a0, 15
413417
; RV32I-NEXT: andi a0, a0, -16
414418
; RV32I-NEXT: sub a0, sp, a0
415-
; RV32I-NEXT: lui a2, 1
419+
; RV32I-NEXT: lui a1, 1
416420
; RV32I-NEXT: .LBB4_1: # %entry
417421
; RV32I-NEXT: # =>This Inner Loop Header: Depth=1
418-
; RV32I-NEXT: sub sp, sp, a2
422+
; RV32I-NEXT: sub sp, sp, a1
419423
; RV32I-NEXT: sw zero, 0(sp)
420424
; RV32I-NEXT: blt a0, sp, .LBB4_1
421425
; RV32I-NEXT: # %bb.2: # %entry
422426
; RV32I-NEXT: mv sp, a0
427+
; RV32I-NEXT: lui a1, 1
428+
; RV32I-NEXT: sub sp, sp, a1
429+
; RV32I-NEXT: sw zero, 0(sp)
430+
; RV32I-NEXT: addi sp, sp, -32
431+
; RV32I-NEXT: sw zero, 0(sp)
423432
; RV32I-NEXT: call callee_stack_args
433+
; RV32I-NEXT: lui a0, 1
434+
; RV32I-NEXT: addi a0, a0, 32
435+
; RV32I-NEXT: add sp, sp, a0
424436
; RV32I-NEXT: addi sp, s0, -16
425437
; RV32I-NEXT: .cfi_def_cfa sp, 16
426438
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
@@ -432,48 +444,70 @@ define void @no_reserved_call_frame(i64 %n, i32 %dummy) #0 {
432444
; RV32I-NEXT: ret
433445
entry:
434446
%v = alloca i32, i64 %n
435-
call void @callee_stack_args(ptr %v, i32 %dummy)
447+
call void @callee_stack_args(ptr %v, [518 x i64] poison)
436448
ret void
437449
}
438450

439451
; Same as above but without a variable-sized allocation, so the reserved call
440452
; frame can be folded into the fixed-size allocation in the prologue.
441-
define void @reserved_call_frame(i64 %n, i32 %dummy) #0 {
453+
define void @reserved_call_frame(i64 %n) #0 {
442454
; RV64I-LABEL: reserved_call_frame:
443455
; RV64I: # %bb.0: # %entry
444-
; RV64I-NEXT: addi sp, sp, -416
445-
; RV64I-NEXT: .cfi_def_cfa_offset 416
446-
; RV64I-NEXT: sd ra, 408(sp) # 8-byte Folded Spill
456+
; RV64I-NEXT: addi sp, sp, -2032
457+
; RV64I-NEXT: .cfi_def_cfa_offset 2032
458+
; RV64I-NEXT: sd ra, 2024(sp) # 8-byte Folded Spill
447459
; RV64I-NEXT: .cfi_offset ra, -8
448-
; RV64I-NEXT: addi a0, sp, 8
460+
; RV64I-NEXT: lui a0, 1
461+
; RV64I-NEXT: sub sp, sp, a0
462+
; RV64I-NEXT: sd zero, 0(sp)
463+
; RV64I-NEXT: .cfi_def_cfa_offset 4096
464+
; RV64I-NEXT: addi sp, sp, -48
465+
; RV64I-NEXT: .cfi_def_cfa_offset 4144
466+
; RV64I-NEXT: lui a0, 1
467+
; RV64I-NEXT: add a0, sp, a0
449468
; RV64I-NEXT: call callee_stack_args
450-
; RV64I-NEXT: ld ra, 408(sp) # 8-byte Folded Reload
469+
; RV64I-NEXT: lui a0, 1
470+
; RV64I-NEXT: addiw a0, a0, 48
471+
; RV64I-NEXT: add sp, sp, a0
472+
; RV64I-NEXT: .cfi_def_cfa_offset 2032
473+
; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload
451474
; RV64I-NEXT: .cfi_restore ra
452-
; RV64I-NEXT: addi sp, sp, 416
475+
; RV64I-NEXT: addi sp, sp, 2032
453476
; RV64I-NEXT: .cfi_def_cfa_offset 0
454477
; RV64I-NEXT: ret
455478
;
456479
; RV32I-LABEL: reserved_call_frame:
457480
; RV32I: # %bb.0: # %entry
458-
; RV32I-NEXT: addi sp, sp, -416
459-
; RV32I-NEXT: .cfi_def_cfa_offset 416
460-
; RV32I-NEXT: sw ra, 412(sp) # 4-byte Folded Spill
481+
; RV32I-NEXT: addi sp, sp, -2032
482+
; RV32I-NEXT: .cfi_def_cfa_offset 2032
483+
; RV32I-NEXT: sw ra, 2028(sp) # 4-byte Folded Spill
461484
; RV32I-NEXT: .cfi_offset ra, -4
462-
; RV32I-NEXT: mv a1, a2
463-
; RV32I-NEXT: addi a0, sp, 12
485+
; RV32I-NEXT: lui a0, 1
486+
; RV32I-NEXT: sub sp, sp, a0
487+
; RV32I-NEXT: sw zero, 0(sp)
488+
; RV32I-NEXT: .cfi_def_cfa_offset 4096
489+
; RV32I-NEXT: addi sp, sp, -80
490+
; RV32I-NEXT: .cfi_def_cfa_offset 4176
491+
; RV32I-NEXT: lui a0, 1
492+
; RV32I-NEXT: addi a0, a0, 36
493+
; RV32I-NEXT: add a0, sp, a0
464494
; RV32I-NEXT: call callee_stack_args
465-
; RV32I-NEXT: lw ra, 412(sp) # 4-byte Folded Reload
495+
; RV32I-NEXT: lui a0, 1
496+
; RV32I-NEXT: addi a0, a0, 80
497+
; RV32I-NEXT: add sp, sp, a0
498+
; RV32I-NEXT: .cfi_def_cfa_offset 2032
499+
; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload
466500
; RV32I-NEXT: .cfi_restore ra
467-
; RV32I-NEXT: addi sp, sp, 416
501+
; RV32I-NEXT: addi sp, sp, 2032
468502
; RV32I-NEXT: .cfi_def_cfa_offset 0
469503
; RV32I-NEXT: ret
470504
entry:
471-
%v = alloca i32, i64 100
472-
call void @callee_stack_args(ptr %v, i32 %dummy)
505+
%v = alloca i32, i64 518
506+
call void @callee_stack_args(ptr %v, [518 x i64] poison)
473507
ret void
474508
}
475509

476-
declare void @callee_stack_args(ptr, i32)
510+
declare void @callee_stack_args(ptr, [518 x i64])
477511

478512
; Dynamic allocation of vectors
479513
define void @dynamic_vector(i64 %size, ptr %out) #0 {

0 commit comments

Comments
 (0)