blob: bfe3eec1eecfd8cb958b56fcc8d9eaba12d165f9 [file]
; RUN: llc -mtriple=x86_64-linux -no-stack-coloring=false -debug-only=stack-coloring < %s -o /dev/null 2>&1 | FileCheck %s
; REQUIRES: asserts
declare i32 @setjmp(ptr) returns_twice
declare void @baz(ptr)
declare void @stash(ptr, ptr)
declare void @use(ptr)
; CHECK-LABEL: setjmp_test
; CHECK: Conservative slots : { 1 1 }
; CHECK: Merge 0 slots
; Test that volatile stack slots accessed after setjmp are not merged.
; Volatile variables must retain their values across longjmp, so their
; stack slots cannot be reused even if their lifetimes don't overlap.
define void @setjmp_test(ptr %jump_buffer) {
entry:
%foo = alloca i32
%bar = alloca [100 x i32]
call void @llvm.lifetime.start.p0(ptr %foo)
call void @llvm.lifetime.start.p0(ptr %bar)
%setjmp_result = call i32 @setjmp(ptr %jump_buffer)
%cmp = icmp eq i32 %setjmp_result, 0
br i1 %cmp, label %after_setjmp, label %continue
after_setjmp:
store volatile i32 100, ptr %foo
br label %exit
continue:
store i32 100, ptr %bar
call void @baz(ptr %bar)
call void @llvm.lifetime.end.p0(ptr %foo)
call void @llvm.lifetime.end.p0(ptr %bar)
br label %exit
exit:
ret void
}
; CHECK-LABEL: setjmp_test_2
; CHECK: Conservative slots : { 1 1 }
; CHECK: Merge 0 slots
; test1 and test2 cannot be merged because they are passed to functions (stash
; and use). Lack of volatile doesn't change anything -- here we don't expect
; the values of test1 and test2 to be preserved, but their addresses/location
; on stack.
%struct.T = type { [100 x i32] }
define void @setjmp_test_2(ptr %jump_buffer) {
entry:
%test1 = alloca %struct.T
%test2 = alloca %struct.T
call void @llvm.lifetime.start.p0(ptr %test1)
%call = call i32 @setjmp(ptr %jump_buffer)
%cmp = icmp eq i32 %call, 0
br i1 %cmp, label %if.then, label %if.else
if.then:
call void @stash(ptr %jump_buffer, ptr %test1)
br label %if.end
if.else:
call void @llvm.lifetime.start.p0(ptr %test2)
call void @use(ptr %test2)
call void @llvm.lifetime.end.p0(ptr %test2)
br label %if.end
if.end:
call void @llvm.lifetime.end.p0(ptr %test1)
ret void
}