You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.4 KiB
243 lines
7.4 KiB
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 -O3 | FileCheck %s
|
|
;
|
|
; Test stack clash protection probing for static allocas.
|
|
|
|
; Small: one probe.
|
|
define i32 @fun0() #0 {
|
|
; CHECK-LABEL: fun0:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: aghi %r15, -560
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 720
|
|
; CHECK-NEXT: cg %r0, 552(%r15)
|
|
; CHECK-NEXT: mvhi 552(%r15), 1
|
|
; CHECK-NEXT: l %r2, 160(%r15)
|
|
; CHECK-NEXT: aghi %r15, 560
|
|
; CHECK-NEXT: br %r14
|
|
|
|
%a = alloca i32, i64 100
|
|
%b = getelementptr inbounds i32, i32* %a, i64 98
|
|
store volatile i32 1, i32* %b
|
|
%c = load volatile i32, i32* %a
|
|
ret i32 %c
|
|
}
|
|
|
|
; Medium: two probes.
|
|
define i32 @fun1() #0 {
|
|
; CHECK-LABEL: fun1:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: aghi %r15, -4096
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 4256
|
|
; CHECK-NEXT: cg %r0, 4088(%r15)
|
|
; CHECK-NEXT: aghi %r15, -4080
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 8336
|
|
; CHECK-NEXT: cg %r0, 4072(%r15)
|
|
; CHECK-NEXT: mvhi 976(%r15), 1
|
|
; CHECK-NEXT: l %r2, 176(%r15)
|
|
; CHECK-NEXT: aghi %r15, 8176
|
|
; CHECK-NEXT: br %r14
|
|
|
|
%a = alloca i32, i64 2000
|
|
%b = getelementptr inbounds i32, i32* %a, i64 200
|
|
store volatile i32 1, i32* %b
|
|
%c = load volatile i32, i32* %a
|
|
ret i32 %c
|
|
}
|
|
|
|
; Large: Use a loop to allocate and probe in steps.
|
|
define i32 @fun2() #0 {
|
|
; CHECK-LABEL: fun2:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: lgr %r1, %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r1
|
|
; CHECK-NEXT: agfi %r1, -69632
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 69792
|
|
; CHECK-NEXT: .LBB2_1: # =>This Inner Loop Header: Depth=1
|
|
; CHECK-NEXT: aghi %r15, -4096
|
|
; CHECK-NEXT: cg %r0, 4088(%r15)
|
|
; CHECK-NEXT: clgrjh %r15, %r1, .LBB2_1
|
|
; CHECK-NEXT: # %bb.2:
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r15
|
|
; CHECK-NEXT: aghi %r15, -2544
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 72336
|
|
; CHECK-NEXT: cg %r0, 2536(%r15)
|
|
; CHECK-NEXT: lhi %r0, 1
|
|
; CHECK-NEXT: mvhi 568(%r15), 1
|
|
; CHECK-NEXT: sty %r0, 28968(%r15)
|
|
; CHECK-NEXT: l %r2, 176(%r15)
|
|
; CHECK-NEXT: agfi %r15, 72176
|
|
; CHECK-NEXT: br %r14
|
|
|
|
%a = alloca i32, i64 18000
|
|
%b0 = getelementptr inbounds i32, i32* %a, i64 98
|
|
%b1 = getelementptr inbounds i32, i32* %a, i64 7198
|
|
store volatile i32 1, i32* %b0
|
|
store volatile i32 1, i32* %b1
|
|
%c = load volatile i32, i32* %a
|
|
ret i32 %c
|
|
}
|
|
|
|
; Ends evenly on the step so no remainder needed.
|
|
define void @fun3() #0 {
|
|
; CHECK-LABEL: fun3:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: lgr %r1, %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r1
|
|
; CHECK-NEXT: aghi %r1, -28672
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 28832
|
|
; CHECK-NEXT: .LBB3_1: # %entry
|
|
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
|
|
; CHECK-NEXT: aghi %r15, -4096
|
|
; CHECK-NEXT: cg %r0, 4088(%r15)
|
|
; CHECK-NEXT: clgrjh %r15, %r1, .LBB3_1
|
|
; CHECK-NEXT: # %bb.2: # %entry
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r15
|
|
; CHECK-NEXT: mvhi 180(%r15), 0
|
|
; CHECK-NEXT: l %r0, 180(%r15)
|
|
; CHECK-NEXT: aghi %r15, 28672
|
|
; CHECK-NEXT: br %r14
|
|
entry:
|
|
%stack = alloca [7122 x i32], align 4
|
|
%i = alloca i32, align 4
|
|
%0 = bitcast [7122 x i32]* %stack to i8*
|
|
%i.0.i.0..sroa_cast = bitcast i32* %i to i8*
|
|
store volatile i32 0, i32* %i, align 4
|
|
%i.0.i.0.6 = load volatile i32, i32* %i, align 4
|
|
ret void
|
|
}
|
|
|
|
; Loop with bigger step.
|
|
define void @fun4() #0 "stack-probe-size"="8192" {
|
|
; CHECK-LABEL: fun4:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: lgr %r1, %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r1
|
|
; CHECK-NEXT: aghi %r1, -24576
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 24736
|
|
; CHECK-NEXT: .LBB4_1: # %entry
|
|
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
|
|
; CHECK-NEXT: aghi %r15, -8192
|
|
; CHECK-NEXT: cg %r0, 8184(%r15)
|
|
; CHECK-NEXT: clgrjh %r15, %r1, .LBB4_1
|
|
; CHECK-NEXT: # %bb.2: # %entry
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r15
|
|
; CHECK-NEXT: aghi %r15, -7608
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 32344
|
|
; CHECK-NEXT: cg %r0, 7600(%r15)
|
|
; CHECK-NEXT: mvhi 180(%r15), 0
|
|
; CHECK-NEXT: l %r0, 180(%r15)
|
|
; CHECK-NEXT: aghi %r15, 32184
|
|
; CHECK-NEXT: br %r14
|
|
entry:
|
|
%stack = alloca [8000 x i32], align 4
|
|
%i = alloca i32, align 4
|
|
%0 = bitcast [8000 x i32]* %stack to i8*
|
|
%i.0.i.0..sroa_cast = bitcast i32* %i to i8*
|
|
store volatile i32 0, i32* %i, align 4
|
|
%i.0.i.0.6 = load volatile i32, i32* %i, align 4
|
|
ret void
|
|
}
|
|
|
|
; Probe size should be modulo stack alignment.
|
|
define void @fun5() #0 "stack-probe-size"="4100" {
|
|
; CHECK-LABEL: fun5:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: aghi %r15, -4096
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 4256
|
|
; CHECK-NEXT: cg %r0, 4088(%r15)
|
|
; CHECK-NEXT: aghi %r15, -88
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 4344
|
|
; CHECK-NEXT: cg %r0, 80(%r15)
|
|
; CHECK-NEXT: mvhi 180(%r15), 0
|
|
; CHECK-NEXT: l %r0, 180(%r15)
|
|
; CHECK-NEXT: aghi %r15, 4184
|
|
; CHECK-NEXT: br %r14
|
|
entry:
|
|
%stack = alloca [1000 x i32], align 4
|
|
%i = alloca i32, align 4
|
|
%0 = bitcast [1000 x i32]* %stack to i8*
|
|
%i.0.i.0..sroa_cast = bitcast i32* %i to i8*
|
|
store volatile i32 0, i32* %i, align 4
|
|
%i.0.i.0.6 = load volatile i32, i32* %i, align 4
|
|
ret void
|
|
}
|
|
|
|
; The minimum probe size is the stack alignment.
|
|
define void @fun6() #0 "stack-probe-size"="5" {
|
|
; CHECK-LABEL: fun6:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: lgr %r1, %r15
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r1
|
|
; CHECK-NEXT: aghi %r1, -4184
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 4344
|
|
; CHECK-NEXT: .LBB6_1: # %entry
|
|
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
|
|
; CHECK-NEXT: aghi %r15, -8
|
|
; CHECK-NEXT: cg %r0, 0(%r15)
|
|
; CHECK-NEXT: clgrjh %r15, %r1, .LBB6_1
|
|
; CHECK-NEXT: # %bb.2: # %entry
|
|
; CHECK-NEXT: .cfi_def_cfa_register %r15
|
|
; CHECK-NEXT: mvhi 180(%r15), 0
|
|
; CHECK-NEXT: l %r0, 180(%r15)
|
|
; CHECK-NEXT: aghi %r15, 4184
|
|
; CHECK-NEXT: br %r14
|
|
entry:
|
|
%stack = alloca [1000 x i32], align 4
|
|
%i = alloca i32, align 4
|
|
%0 = bitcast [1000 x i32]* %stack to i8*
|
|
%i.0.i.0..sroa_cast = bitcast i32* %i to i8*
|
|
store volatile i32 0, i32* %i, align 4
|
|
%i.0.i.0.6 = load volatile i32, i32* %i, align 4
|
|
ret void
|
|
}
|
|
|
|
; Small with a natural probe (STMG) - needs no extra probe.
|
|
define i32 @fun7() #0 {
|
|
; CHECK-LABEL: fun7:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -3976
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 4136
|
|
; CHECK-NEXT: brasl %r14, foo@PLT
|
|
; CHECK-NEXT: st %r2, 568(%r15)
|
|
; CHECK-NEXT: l %r2, 176(%r15)
|
|
; CHECK-NEXT: lmg %r14, %r15, 4088(%r15)
|
|
; CHECK-NEXT: br %r14
|
|
%v = call i32 @foo()
|
|
%a = alloca i32, i64 950
|
|
%b = getelementptr inbounds i32, i32* %a, i64 98
|
|
store volatile i32 %v, i32* %b
|
|
%c = load volatile i32, i32* %a
|
|
ret i32 %c
|
|
}
|
|
|
|
; Medium with an STMG - still needs probing.
|
|
define i32 @fun8() #0 {
|
|
; CHECK-LABEL: fun8:
|
|
; CHECK: # %bb.0:
|
|
; CHECK-NEXT: stmg %r14, %r15, 112(%r15)
|
|
; CHECK-NEXT: .cfi_offset %r14, -48
|
|
; CHECK-NEXT: .cfi_offset %r15, -40
|
|
; CHECK-NEXT: aghi %r15, -3984
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 4144
|
|
; CHECK-NEXT: cg %r0, 3976(%r15)
|
|
; CHECK-NEXT: brasl %r14, foo@PLT
|
|
; CHECK-NEXT: st %r2, 976(%r15)
|
|
; CHECK-NEXT: l %r2, 176(%r15)
|
|
; CHECK-NEXT: lmg %r14, %r15, 4096(%r15)
|
|
; CHECK-NEXT: br %r14
|
|
|
|
%v = call i32 @foo()
|
|
%a = alloca i32, i64 952
|
|
%b = getelementptr inbounds i32, i32* %a, i64 200
|
|
store volatile i32 %v, i32* %b
|
|
%c = load volatile i32, i32* %a
|
|
ret i32 %c
|
|
}
|
|
|
|
declare i32 @foo()
|
|
attributes #0 = { "probe-stack"="inline-asm" }
|
|
|