ELF: Have __rela_iplt_{start,end} surround .rela.iplt with --pack-dyn-relocs=android.
[llvm-project.git] / llvm / test / Transforms / Inline / dynamic-alloca-simplified-large.ll
blob9b293d39c85f959f14cea1d090b1e7516a84c1dd
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2 ; RUN: opt -passes=inline < %s -S -o - | FileCheck %s
3 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-apple-macosx10.15.0"
6 define void @caller1(ptr %p1, i1 %b) {
7 ; CHECK-LABEL: define {{[^@]+}}@caller1
8 ; CHECK-SAME: (ptr [[P1:%.*]], i1 [[B:%.*]]) {
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B]], true
11 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
12 ; CHECK:       split:
13 ; CHECK-NEXT:    call void @callee(ptr [[P1]], i32 0, i32 -1)
14 ; CHECK-NEXT:    br label [[EXIT]]
15 ; CHECK:       exit:
16 ; CHECK-NEXT:    ret void
18 entry:
19   %cond = icmp eq i1 %b, true
20   br i1 %cond, label %exit, label %split
22 split:
23   ; This path may be generated from CS splitting and never taken at runtime.
24   call void @callee(ptr %p1, i32 0, i32 -1)
25   br label %exit
27 exit:
28   ret void
31 define  void @callee(ptr %p1, i32 %l1, i32 %l2) {
32 ; CHECK-LABEL: define {{[^@]+}}@callee
33 ; CHECK-SAME: (ptr [[P1:%.*]], i32 [[L1:%.*]], i32 [[L2:%.*]]) {
34 ; CHECK-NEXT:  entry:
35 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[L2]] to i64
36 ; CHECK-NEXT:    [[VLA:%.*]] = alloca float, i64 [[EXT]], align 16
37 ; CHECK-NEXT:    call void @extern_call(ptr nonnull [[VLA]]) #[[ATTR3:[0-9]+]]
38 ; CHECK-NEXT:    ret void
40 entry:
41   %ext = zext i32 %l2 to i64
42   %vla = alloca float, i64 %ext, align 16
43   call void @extern_call(ptr nonnull %vla) #3
44   ret void
48 define void @caller2_below_threshold(ptr %p1, i1 %b) {
49 ; CHECK-LABEL: define {{[^@]+}}@caller2_below_threshold
50 ; CHECK-SAME: (ptr [[P1:%.*]], i1 [[B:%.*]]) {
51 ; CHECK-NEXT:  entry:
52 ; CHECK-NEXT:    [[VLA_I:%.*]] = alloca float, i64 15000, align 16
53 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B]], true
54 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
55 ; CHECK:       split:
56 ; CHECK-NEXT:    [[SAVEDSTACK:%.*]] = call ptr @llvm.stacksave.p0()
57 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 60000, ptr [[VLA_I]])
58 ; CHECK-NEXT:    call void @extern_call(ptr nonnull [[VLA_I]]) #[[ATTR3]]
59 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 60000, ptr [[VLA_I]])
60 ; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[SAVEDSTACK]])
61 ; CHECK-NEXT:    br label [[EXIT]]
62 ; CHECK:       exit:
63 ; CHECK-NEXT:    ret void
65 entry:
66   %cond = icmp eq i1 %b, true
67   br i1 %cond, label %exit, label %split
69 split:
70   call void @callee(ptr %p1, i32 0, i32 15000)
71   br label %exit
73 exit:
74   ret void
77 define  void @callee2_not_in_entry(ptr %p1, i32 %l1, i32 %l2) {
78 ; CHECK-LABEL: define {{[^@]+}}@callee2_not_in_entry
79 ; CHECK-SAME: (ptr [[P1:%.*]], i32 [[L1:%.*]], i32 [[L2:%.*]]) {
80 ; CHECK-NEXT:  entry:
81 ; CHECK-NEXT:    [[EXT:%.*]] = zext i32 [[L2]] to i64
82 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[L1]], 42
83 ; CHECK-NEXT:    br i1 [[C]], label [[BB2:%.*]], label [[BB3:%.*]]
84 ; CHECK:       bb2:
85 ; CHECK-NEXT:    [[VLA:%.*]] = alloca float, i64 [[EXT]], align 16
86 ; CHECK-NEXT:    call void @extern_call(ptr nonnull [[VLA]]) #[[ATTR3]]
87 ; CHECK-NEXT:    ret void
88 ; CHECK:       bb3:
89 ; CHECK-NEXT:    ret void
91 entry:
92   %ext = zext i32 %l2 to i64
93   %c = icmp eq i32 %l1, 42
94   br i1 %c, label %bb2, label %bb3
95 bb2:
96   %vla = alloca float, i64 %ext, align 16
97   call void @extern_call(ptr nonnull %vla) #3
98   ret void
99 bb3:
100   ret void
103 define void @caller3_alloca_not_in_entry(ptr %p1, i1 %b) {
104 ; CHECK-LABEL: define {{[^@]+}}@caller3_alloca_not_in_entry
105 ; CHECK-SAME: (ptr [[P1:%.*]], i1 [[B:%.*]]) {
106 ; CHECK-NEXT:  entry:
107 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B]], true
108 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
109 ; CHECK:       split:
110 ; CHECK-NEXT:    br label [[EXIT]]
111 ; CHECK:       exit:
112 ; CHECK-NEXT:    ret void
114 entry:
115   %cond = icmp eq i1 %b, true
116   br i1 %cond, label %exit, label %split
118 split:
119   call void @callee2_not_in_entry(ptr %p1, i32 0, i32 -1)
120   br label %exit
122 exit:
123   ret void
126 define void @caller4_over_threshold(ptr %p1, i1 %b, i32 %len) {
127 ; CHECK-LABEL: define {{[^@]+}}@caller4_over_threshold
128 ; CHECK-SAME: (ptr [[P1:%.*]], i1 [[B:%.*]], i32 [[LEN:%.*]]) {
129 ; CHECK-NEXT:  entry:
130 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i1 [[B]], true
131 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[SPLIT:%.*]]
132 ; CHECK:       split:
133 ; CHECK-NEXT:    call void @callee(ptr [[P1]], i32 0, i32 16500)
134 ; CHECK-NEXT:    br label [[EXIT]]
135 ; CHECK:       exit:
136 ; CHECK-NEXT:    ret void
138 entry:
139   %cond = icmp eq i1 %b, true
140   br i1 %cond, label %exit, label %split
142 split:
143   call void @callee(ptr %p1, i32 0, i32 16500)
144   br label %exit
146 exit:
147   ret void
150 declare noalias ptr @malloc(i64)
151 define ptr @stack_allocate(i32 %size) #2 {
152 ; CHECK-LABEL: define {{[^@]+}}@stack_allocate
153 ; CHECK-SAME: (i32 [[SIZE:%.*]]) #[[ATTR0:[0-9]+]] {
154 ; CHECK-NEXT:  entry:
155 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[SIZE]], 100
156 ; CHECK-NEXT:    [[CONV:%.*]] = zext i32 [[SIZE]] to i64
157 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
158 ; CHECK:       if.then:
159 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca i8, i64 [[CONV]], align 8
160 ; CHECK-NEXT:    br label [[RETURN:%.*]]
161 ; CHECK:       if.end:
162 ; CHECK-NEXT:    [[CALL:%.*]] = tail call ptr @malloc(i64 [[CONV]]) #[[ATTR3]]
163 ; CHECK-NEXT:    br label [[RETURN]]
164 ; CHECK:       return:
165 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[TMP0]], [[IF_THEN]] ], [ [[CALL]], [[IF_END]] ]
166 ; CHECK-NEXT:    ret ptr [[RETVAL_0]]
168 entry:
169   %cmp = icmp ult i32 %size, 100
170   %conv = zext i32 %size to i64
171   br i1 %cmp, label %if.then, label %if.end
173 if.then:                                          ; preds = %entry
174   %0 = alloca i8, i64 %conv, align 8
175   br label %return
177 if.end:                                           ; preds = %entry
178   %call = tail call ptr @malloc(i64 %conv) #3
179   br label %return
181 return:                                           ; preds = %if.end, %if.then
182   %retval.0 = phi ptr [ %0, %if.then ], [ %call, %if.end ]
183   ret ptr %retval.0
186 define ptr @test_stack_allocate_always(i32 %size) {
187 ; CHECK-LABEL: define {{[^@]+}}@test_stack_allocate_always
188 ; CHECK-SAME: (i32 [[SIZE:%.*]]) {
189 ; CHECK-NEXT:  entry:
190 ; CHECK-NEXT:    [[SAVEDSTACK:%.*]] = call ptr @llvm.stacksave.p0()
191 ; CHECK-NEXT:    [[CMP_I:%.*]] = icmp ult i32 [[SIZE]], 100
192 ; CHECK-NEXT:    [[CONV_I:%.*]] = zext i32 [[SIZE]] to i64
193 ; CHECK-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
194 ; CHECK:       if.then.i:
195 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca i8, i64 [[CONV_I]], align 8
196 ; CHECK-NEXT:    br label [[STACK_ALLOCATE_EXIT:%.*]]
197 ; CHECK:       if.end.i:
198 ; CHECK-NEXT:    [[CALL_I:%.*]] = tail call ptr @malloc(i64 [[CONV_I]]) #[[ATTR3]]
199 ; CHECK-NEXT:    br label [[STACK_ALLOCATE_EXIT]]
200 ; CHECK:       stack_allocate.exit:
201 ; CHECK-NEXT:    [[RETVAL_0_I:%.*]] = phi ptr [ [[TMP0]], [[IF_THEN_I]] ], [ [[CALL_I]], [[IF_END_I]] ]
202 ; CHECK-NEXT:    call void @llvm.stackrestore.p0(ptr [[SAVEDSTACK]])
203 ; CHECK-NEXT:    ret ptr [[RETVAL_0_I]]
205 entry:
206   %call = tail call ptr @stack_allocate(i32 %size)
207   ret ptr %call
210 declare void @extern_call(ptr)
212 attributes #1 = { argmemonly nounwind willreturn writeonly }
213 attributes #2 = { alwaysinline }
214 attributes #3 = { nounwind }