[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / GlobalOpt / preallocated.ll
blob8eb9bca6804af677ddda8c76de5b6f75b7610f80
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt < %s -passes=globalopt -S | FileCheck %s
4 declare token @llvm.call.preallocated.setup(i32)
5 declare ptr @llvm.call.preallocated.arg(token, i32)
6 declare i32 @__CxxFrameHandler3(...)
8 ; Don't touch functions with any musttail calls
9 define internal i32 @preallocated_musttail(ptr preallocated(i32) %p) {
10 ; CHECK-LABEL: define {{[^@]+}}@preallocated_musttail
11 ; CHECK-SAME: (ptr preallocated(i32) [[P:%.*]]) unnamed_addr {
12 ; CHECK-NEXT:    [[RV:%.*]] = load i32, ptr [[P]], align 4
13 ; CHECK-NEXT:    ret i32 [[RV]]
15   %rv = load i32, ptr %p
16   ret i32 %rv
19 define i32 @call_preallocated_musttail(ptr preallocated(i32) %a) {
20 ; CHECK-LABEL: define {{[^@]+}}@call_preallocated_musttail
21 ; CHECK-SAME: (ptr preallocated(i32) [[A:%.*]]) local_unnamed_addr {
22 ; CHECK-NEXT:    [[R:%.*]] = musttail call i32 @preallocated_musttail(ptr preallocated(i32) [[A]])
23 ; CHECK-NEXT:    ret i32 [[R]]
25   %r = musttail call i32 @preallocated_musttail(ptr preallocated(i32) %a)
26   ret i32 %r
29 define i32 @call_preallocated_musttail_without_musttail() {
30 ; CHECK-LABEL: define {{[^@]+}}@call_preallocated_musttail_without_musttail() local_unnamed_addr {
31 ; CHECK-NEXT:    [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
32 ; CHECK-NEXT:    [[N:%.*]] = call ptr @llvm.call.preallocated.arg(token [[C]], i32 0) #[[ATTR1:[0-9]+]]
33 ; CHECK-NEXT:    [[R:%.*]] = call i32 @preallocated_musttail(ptr preallocated(i32) [[N]]) [ "preallocated"(token [[C]]) ]
34 ; CHECK-NEXT:    ret i32 [[R]]
36   %c = call token @llvm.call.preallocated.setup(i32 1)
37   %N = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
38   %r = call i32 @preallocated_musttail(ptr preallocated(i32) %N) ["preallocated"(token %c)]
39   ret i32 %r
42 ; Check that only one alloca per preallocated arg
43 define internal i32 @preallocated(ptr preallocated(i32) %a) {
44 ; CHECK-LABEL: define {{[^@]+}}@preallocated
45 ; CHECK-SAME: (ptr [[A:%.*]]) unnamed_addr {
46 ; CHECK-NEXT:    [[RV:%.*]] = load i32, ptr [[A]], align 4
47 ; CHECK-NEXT:    ret i32 [[RV]]
49   %rv = load i32, ptr %a
50   ret i32 %rv
53 declare void @foo(ptr)
55 define i32 @call_preallocated_multiple_args() {
56 ; CHECK-LABEL: define {{[^@]+}}@call_preallocated_multiple_args() local_unnamed_addr {
57 ; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @llvm.stacksave.p0()
58 ; CHECK-NEXT:    [[PAARG:%.*]] = alloca i32, align 4
59 ; CHECK-NEXT:    call void @foo(ptr [[PAARG]])
60 ; CHECK-NEXT:    call void @foo(ptr [[PAARG]])
61 ; CHECK-NEXT:    call void @foo(ptr [[PAARG]])
62 ; CHECK-NEXT:    [[R:%.*]] = call fastcc i32 @preallocated(ptr [[PAARG]])
63 ; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[TMP1]])
64 ; CHECK-NEXT:    ret i32 [[R]]
66   %c = call token @llvm.call.preallocated.setup(i32 1)
67   %a1 = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
68   call void @foo(ptr %a1)
69   %a2 = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
70   call void @foo(ptr %a2)
71   %a3 = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
72   call void @foo(ptr %a3)
73   %r = call i32 @preallocated(ptr preallocated(i32) %a3) ["preallocated"(token %c)]
74   ret i32 %r
77 ; Don't touch functions with any invokes
78 define internal i32 @preallocated_invoke(ptr preallocated(i32) %p) {
79 ; CHECK-LABEL: define {{[^@]+}}@preallocated_invoke
80 ; CHECK-SAME: (ptr preallocated(i32) [[P:%.*]]) unnamed_addr {
81 ; CHECK-NEXT:    [[RV:%.*]] = load i32, ptr [[P]], align 4
82 ; CHECK-NEXT:    ret i32 [[RV]]
84   %rv = load i32, ptr %p
85   ret i32 %rv
88 define i32 @call_preallocated_invoke() personality ptr @__CxxFrameHandler3 {
89 ; CHECK-LABEL: define {{[^@]+}}@call_preallocated_invoke() local_unnamed_addr personality ptr @__CxxFrameHandler3 {
90 ; CHECK-NEXT:    [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
91 ; CHECK-NEXT:    [[A:%.*]] = call ptr @llvm.call.preallocated.arg(token [[C]], i32 0) #[[ATTR1]]
92 ; CHECK-NEXT:    [[R:%.*]] = invoke i32 @preallocated_invoke(ptr preallocated(i32) [[A]]) [ "preallocated"(token [[C]]) ]
93 ; CHECK-NEXT:    to label [[CONTA:%.*]] unwind label [[CONTB:%.*]]
94 ; CHECK:       conta:
95 ; CHECK-NEXT:    ret i32 [[R]]
96 ; CHECK:       contb:
97 ; CHECK-NEXT:    [[S:%.*]] = catchswitch within none [label %catch] unwind to caller
98 ; CHECK:       catch:
99 ; CHECK-NEXT:    [[P:%.*]] = catchpad within [[S]] []
100 ; CHECK-NEXT:    catchret from [[P]] to label [[CONT:%.*]]
101 ; CHECK:       cont:
102 ; CHECK-NEXT:    ret i32 42
104   %c = call token @llvm.call.preallocated.setup(i32 1)
105   %a = call ptr @llvm.call.preallocated.arg(token %c, i32 0) preallocated(i32)
106   %r = invoke i32 @preallocated_invoke(ptr preallocated(i32) %a) ["preallocated"(token %c)]
107   to label %conta unwind label %contb
108 conta:
109   ret i32 %r
110 contb:
111   %s = catchswitch within none [label %catch] unwind to caller
112 catch:
113   %p = catchpad within %s []
114   catchret from %p to label %cont
115 cont:
116   ret i32 42